Reading and writing files via fs:

 const content = fs.readFileSync(this.entry,'utf-8')
 fs.writeFileSync(this.outputFile,content,'utf-8')
Copy the code

Parse the file with ‘@babel/core’

Read dependencies and content (define complier methods)

  • Babel. parseSync: Converts content to abstract syntax trees (essentially using @babel/parser)
var babel = require('@babel/core') const parseAst = babel.parseSync(content,{sourceType:'module'}) Console. log(parseast.program.body) /* [Node {type: 'ImportDeclaration',// start: 0, end: 23, loc: SourceLocation { start: [Position], end: [Position], filename: undefined, identifierName: undefined }, specifiers: [ [Node] ], source: Node { type: 'StringLiteral', start: 14, end: 22, loc: [SourceLocation], extra: [Object], value: './b.js' // reference address}}, Node {type: 'ExportDefaultDeclaration', // output start: 24, end: 48, loc: SourceLocation {start: 24, end: 48, loc: SourceLocation {start: [Position], end: [Position], filename: undefined, identifierName: undefined }, declaration: Node { type: 'BinaryExpression', start: 39, end: 48, loc: [SourceLocation], left: [Node], operator: '+', right: [Node] } } ] */Copy the code
  • Babel. TransformFromAstSync: converts content to the browser can identify code
var babel = require('@babel/core') const transformContent = babel.transformFromAstAsync(parseAst,null,{presets:["@babel/preset-env"]}).then(res=>{ console.log(res) }) /** code: '"use strict"; \n' + '\n' + 'Object.defineProperty(exports, "__esModule", {\n' + ' value: true\n' + '}); \n' + 'exports["default"] = void 0; \n' + '\n' + 'var _b = _interopRequireDefault(require("./b.js")); \n' + '\n' + 'function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }\n' + '\n' + `var _default = 'aaaaa' + _b["default"]; \n` + '\n' + 'exports["default"] = _default; ', map: null, */Copy the code
  • Read dependency files: You can parse the content from parse, or use @babel/traverse

Note: with new versions of traverse, the introduction requires default; (const traverse = require('@babel/traverse').default)

Obtaining module data

Obtain module data by performing the preceding operations

{ filepath: './src/index.js', dependencies: { './b.js': './src/b.js' }, code: '"use strict"; \n' + '\n' + 'Object.defineProperty(exports, "__esModule", {\n' + ' value: true\n' + '}); \n' + 'exports["default"] = void 0; \n' + '\n' + 'var _b = _interopRequireDefault(require("./b.js")); \n' + '\n' + 'function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }\n' + '\n' + `var _default = 'aaaaa' + _b["default"]; \n` + '\n' + 'exports["default"] = _default; '}Copy the code

Get all dependent file contents recursively

Modules inserts all dependent files into modules to implement recursion

const module = this.complier(this.entry) this.modules.push(module) for(let i=0; i<this.modules.length; i++){ Object.entries(this.modules[i].dependencies).forEach(dep=>{ this.modules.push(this.complier(dep[1])) }) }Copy the code

Generate modules required by the bundle

const newModules = this.modules.reduce((lastModule,curr)=>{ return {... lastModule,[curr.filepath]:curr} },{})Copy the code

Generating bundle files

The code generated by transform contains require and exports, so you need to define the require function and exports object

Define the require function to return the result

Function require(moduleId){// 1, define exports var exports = {} ModuleId = 'eval(modules[moduleId].code) // 3, return exports}Copy the code

Complete the contents of the bundle

const newModules = this.modules.reduce((lastModule,curr)=>{ return {... lastModule,[curr.filepath]:curr} },{}) let exefun = '(' exefun += `function(modules){ var __myWebpack_exports_cache = {} Var executeCode = (require,exports,code)=>{eval(code)} var executeCode = (require,exports,code)=>{eval(code)} var executeCode = (require,exports,code)=>{eval(code) Function reRequire(path){var newPath = modules[moduleId]. Dependencies [path] if(newPath){return Module [moduleId].dependencies[path])} else {return ()=>{}}} // __myWebpack_exports_cache[moduleId] if(cacheExports){ return cacheExports; Exports var exports = (__myWebpack_exports_cache[moduleId] = {}) // ExecuteCode (reRequire, exports, modules [moduleId] code) / / 4, returning to run results return exports} the require (". / SRC/index. Js ")} )(${JSON.stringify(newModules)})`Copy the code

For details, please check: github.com/logmei/fron…