一.webpack打包流程如下图所示:
二.项目的具体目录结构如下:
1.在根目录下创建run.js,代码如下:
//webpack核心代码 引入webpack模块 let webpack = require('webpack') //获取webpack.config的信息 let options = require('./webpack.config') //complier 挂载钩子 处理打包流程 let compiler = webpack(options) //调用run方法 按照某种机制执行打包操作 compiler.run((err, stats) => { console.log(err) console.log(stats.toJson({ entries: true, chunks: false, modules: false, assets: false })) })
上述代码实际上运行相当于package.json里面的npm run XX 打包操作
二.下面模拟下打包操作,手写下打包逻辑的实现
首先创建lgPack文件夹充当打包的包名,yarn init,在package.json中改变main目录为./lib/webpack.js,
创建lib文件夹,创建webpack.js
2.1从webpack打包流程中,我们可以梳理下webpack.js部分的流程
1.实例化complier对象
2.初始化NodeEnvironmentgPlugin(让compiler具体文件读写能力) 备注:如果要做打包操作,需要对文件处理,打包之后生成一个新的文件
3.挂载所有plugins插件至complier对象身上
4.挂载所有 webpack内置的插件(入口)
5.返回complier对象即可
出于模块化考虑,创建compiler.js,把complier部分写在complier.js里面 安装tapable,yarn add tapable@版本 -d
在lib下创建node目录,创建complier具有读写能力的NodeEnvironmentPlugin.js
webpack.js的代码如下:
/** * */ const Compiler = require('./Compiler') //自动导包插件 const NodeEnvironmentPlugin = require('./node/NodeEnvironmentPlugin') //const WebpackOptionsApply=require('./WebpackOptionsApply') const webpack = function (options) { //根据run.js options为webpack.config.js // 01 实例化 compiler 对象 let compiler = new Compiler(options.context) //获取当前项目所在的绝对路径 options.context compiler.options = options // 02 初始化 NodeEnvironmentPlugin(让compiler具体文件读写能力) new NodeEnvironmentPlugin().apply(compiler) // 03 挂载所有 plugins 插件至 compiler 对象身上 (compiler就相当于贯穿整个编译过程的,在整个编译过程中到处埋雷) if (options.plugins && Array.isArray(options.plugins)) { for (const plugin of options.plugins) { plugin.apply(compiler) } } // 04 挂载所有 webpack 内置的插件(入口) // compiler.options = new WebpackOptionsApply().process(options, compiler); // 05 返回 compiler 对象即可 return compiler } module.exports = webpack
run.js修改后的代码如下:
// let webpack = require('./lpPack') let webpack = require('./lpPack') let options = require('./webpack.config') let compiler = webpack(options) compiler.run((err, stats) => { console.log(err) console.log(stats.toJson({ entries: true, chunks: false, modules: false, assets: false })) })
NodeEnvironmentPlugin.js代码如下:
const fs = require('fs') class NodeEnvironmentPlugin { constructor(options) { this.options = options || {} } apply(complier) { complier.inputFileSystem = fs complier.outputFileSystem = fs } } module.exports = NodeEnvironmentPlugin
Complier.js代码如下:
const { Tapable, AsyncSeriesHook } = require('tapable') class Compiler extends Tapable { constructor(context) { super() this.context = context this.hooks = { done: new AsyncSeriesHook(["stats"]) } } run(callback) { callback(null, { toJson() { return { entries: [], // 当前次打包的入口信息 chunks: [], // 当前次打包的 chunk 信息 modules: [], // 模块信息 assets: [], // 当前次打包最终生成的资源 } } }) } } module.exports = Compiler
package.json代码如下:
{ "name": "wp_h", "version": "1.0.0", "description": "", "main": "./lib/webpack.js", "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "tapable": "^1.1.3", "webpack": "^4.45.0", "webpack-cli": "^3.3.12" } }
最后在终端中输出node . un.js就可输出对应的结果。