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…