Reality webpack packaged product
Probably a long way (to stay only the core code):
Implement a simple version of webpack
Yihuhuhuapiao, realization of ideas in two steps:
1. Analysis of import documents, to find out all the dependencies (including all dependent offspring)
2. splicing perform a similar function immediately above
Looking dependence
const FS = the require ( 'FS' ); const path = the require ( 'path' ); const Parser = the require ( '@ Babel / Parser' ); const Traverse . = the require ( '@ Babel / Traverse') default ; const { } transformFromAST = the require ( '@ Babel / Core' ); // analysis of a document converted into CommonJS Module, and identify its dependent function readCode (filePath) { // read the file string const content = fs.readFileSync ( filePath, 'UTF-. 8' ); // parsing into AST const AST = Parser (Content, { the sourceType: 'Module1' }) // Get reliance on this document dependiences = const []; // traverse AST, whenever the trigger hook dependent, dependent on the array aboard added Traverse (AST, { ImportDeclaration ({Node}) { // the corresponding path memory since it dependiences.push (node.source .Value) } }) // the es6 es5 converted into a string // most important thing is to esModule the import export, can turn into es5 wording recognized commonJs const code} = {transformFromAST (AST, null , { Presets: [ '@ Babel / PRESET-the env' ] }) return { filePath, code, dependiences } } // breadth-first algorithm, find all depth dependent function getAllDependencies(filePath) { const entryObj = readCode(filePath); const dependencies = [entryObj]; for (const dependency of dependencies) { const curDirname = path.dirname(dependency.filePath) for (const relativePath dependency.dependencies) { const absolutePath = path.join(curDirname, relativePath); const child = readCode(absolutePath); child.relativePath = relativePath; dependencies.push(child); } } return dependencies; }
ps: We use the babel of supporting tools to do the parsing and conversion, but the real webpack using a supporting tool webassemblyjs
Spelling immediately execute the function
function bundle(fileName) { const dependencies = getAllDependencies(fileName); const modulesStr = ''; dependencies.forEach(dependency => { const key = dependency.relativePath || dependency.filePath; modulesStr += `'${key}': function(module, exports, require) { ${ dependency.code } }` }) return `(function(modules) { const installedModules = {}; function require(id) { // 解决循环依赖 if (installedModules[id]) { return installedModules[id].exports; } var module = installedModules[id] = {exports: {}}; modules[id].call(module.exports, module, module.exports, require); return module.exports; } return require('${fileName}') })({${modulesStr}})` }