-
在m-pack 通过path 引入 webpack.config.js
let config = require(path.resolve('webpack.config.js')); console.log(config) 输出: { mode: 'development', entry: './src/index.js', output: { path: 'C:\\Users\\zxw\\Desktop\\js\\handwritten_webback\\webpack-dev\\dist', filename: 'bundle.js' } }
let path = require('path'); module.exports = { mode: 'development', entry: './src/index.js', output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' } }
2. 在bin 创建 Compiler.js 在 m-pack 引入 然后 通过 new 实例化引入的 Compiler 最后 通过 run 方法启动
#! /usr/bin/env node console.log('start 2020') let path = require('path') //配置文件 let config = require(path.resolve('webpack.config.js')); console.log(config) let Compiler = require("../bin/Compiler") let compiler = new Compiler(config); compiler.hooks.entryOption.call(); compiler.run()
-
在constructor 接受传入的配置
-
this.entry 是传入配置的入口文件
-
this.config 将配置挂载到全局上
-
this.root = process.cwd(); 是项目的工作的目录 如: C:\Users\zxw\Desktop\js\handwritten_webback\webpack-dev
-
this.entryId 用来存放主入口
-
buildModules 通过入口文件的路径来 获取源码 构建依赖关系
-
emitFile 用来 最后解析好的源码和依赖关系发射出去
let path = require('path') class Compiler { constructor(config) { this.config = config // 需要保存的主入口文件路径 this.entryId; // './src/index.js' // modules对象用来存放依赖key和源码value this.modules = {}; // 入口路径 entry: './src/index.js', this.entry = config.entry; //工作路径 C:\Users\zxw\Desktop\js\handwritten_webback\webpack-dev this.root = process.cwd(); console.log(path.resolve(this.root, this.entry)) } run() { // C:\Users\zxw\Desktop\js\handwritten_webback\webpack-dev\src\index.js this.buildModules(path.resolve(this.root, this.entry), true); // 发射一个文件 this.emitFile(); } buildModules(modulePath, isEntry) { } // 发射文件 emitFile() { } } module.exports = Compiler;
-
buildModules 详解
-
通过 getSource 拿到模块的内容
let source = this.getSource(modulePath) // let str = require('./a.js') // console.log(str)
-
获取模块的入口
let moduleName = './' + path.relative(this.root, modulePath) console.log(moduleName) ./src\index.js
-
判断如果是入口文件 就将它赋值给this.entryId 如果不是 进行 解析
-
调用 parse 方法进行解析 传入 模块的内容 和 父文件 的目录
buildModules(modulePath, isEntry) { console.log(111) // 拿到模块的内容 let source = this.getSource(modulePath) // console.log(source) //./src\index.js let moduleName = './' + path.relative(this.root, modulePath) // console.log(moduleName) if (isEntry) { // 保存入口 this.entryId = moduleName } console.log(path.dirname(moduleName)) // 解析 需要把source 源码解析 let { sourceCode, dependencies } = this.parse(source, path.dirname(moduleName)) }
parse(source, parentPath) { let dependencies = []; let ast = babylon.parse(source); traverse(ast, { CallExpression(p) { if (p.node.callee.name === 'require') { p.node.callee.name = '__webpack_require__'; let moduleName = p.node.arguments[0].value; moduleName = moduleName + (path.extname(moduleName) ? '' : '.js'); moduleName = './' + path.join(parentPath, moduleName); dependencies.push(moduleName); p.node.arguments = [t.stringLiteral(moduleName)] } } }); let sourceCode = generator(ast).code; return { sourceCode, dependencies }; }
npm i babylon @babel/traverse @babel/types @babel/generator -D
buildModules(modulePath, isEntry) { console.log(111) // 拿到模块的内容 let source = this.getSource(modulePath) // console.log(source) //./src\index.js let moduleName = './' + path.relative(this.root, modulePath) // console.log(moduleName) if (isEntry) { // 保存入口 this.entryId = moduleName } // 解析 需要把source 源码解析 let { sourceCode, dependencies } = this.parse(source, path.dirname(moduleName)) this.modules[moduleName] = sourceCode dependencies.forEach((depend) => { this.buildModules(path.join(this.root, depend), false); }); console.log(this.modules); // console.log(path.dirname(moduleName)) }
{ './src\\index.js': 'let str = __webpack_require__("./src\\\\a.js");\n\nconsole.log(str);', './src\\a.js': 'let b = __webpack_require__("./src\\\\base\\\\b.js");\n\nmodule.exports = b + \'2020\';', './src\\base\\b.js': 'module.exports = \'您好a\';' } { './src\\index.js': 'let str = __webpack_require__("./src\\\\a.js");\n\nconsole.log(str);', './src\\a.js': 'let b = __webpack_require__("./src\\\\base\\\\b.js");\n\nmodule.exports = b + \'2020\';', './src\\base\\b.js': 'module.exports = \'您好a\';' } { './src\\index.js': 'let str = __webpack_require__("./src\\\\a.js");\n\nconsole.log(str);', './src\\a.js': 'let b = __webpack_require__("./src\\\\base\\\\b.js");\n\nmodule.exports = b + \'2020\';', './src\\base\\b.js': 'module.exports = \'您好a\';' }