美文网首页Front End
[FE] webpack v4.20.2 源码解析(一):准备工

[FE] webpack v4.20.2 源码解析(一):准备工

作者: 何幻 | 来源:发表于2018-10-09 17:34 被阅读58次

1. 准备工作

1.1 使用nvm管理node版本

github: creationix/nvm
参考:Node Version Manager

安装完成后:

$ nvm --version
0.33.6

1.2 使用nvm安装最新LTS版的node

$ nvm install --lts
Installing latest LTS version.
v8.12.0 is already installed.
Now using node v8.12.0 (npm v6.4.1)
$ node --version
v8.12.0
$ which npm
~/.nvm/versions/node/v8.12.0/bin/npm

2. webpack工程

2.1 新建debug-webpack文件夹,并初始化

$ mkdir ~/Test/debug-webpack 
$ cd ~/Test/debug-webpack 
$ npm init -f

2.2 添加webpack.config.js和src/index.js

(1)webpack.config.js

const path = require('path');

module.exports = {
    entry: {
        index: path.resolve(__dirname, 'src/index.js'),
    },
    output: {
        path: path.resolve(__dirname, 'dist/'),
    },
    module: {
        rules: [
            { test: /\.js$/, use: { loader: 'babel-loader', query: { presets: ['@babel/preset-env'] } } },
        ]
    },
};

(2)src/index.js

alert();

2.3 安装依赖

$ npm i -g webpack-cli webpack
$ npm i -D babel-loader @babel/core @babel/preset-env

2.4 运行webpack

$ webpack
Hash: 2e91628041d9a877f709
Version: webpack 4.20.2
Time: 639ms
Built at: 2018-10-09 09:25:24
   Asset       Size  Chunks             Chunk Names
index.js  937 bytes       0  [emitted]  index
Entrypoint index = index.js
[0] ./src/index.js 8 bytes {0} [built]

2.5 编译结果

dist/index.js

!function(e){var t={};function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}r.m=e,r.c=t,r.d=function(e,t,n){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="",r(r.s=0)}([function(e,t){alert()}]);

3. 如何向源码中写入log

由于node.js的动态特性,只要找到源码文件,直接修改就可以了,
但是console.log的表现力稍微差一些,下面我们使用debug写日志。

3.1 安装debug依赖

打开源码所在的本地npm包目录,安装debug模块,例如,

$ cd ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack
$ npm i -D debug

3.2 调用debug库

打开本地源码文件,例如,webpack.js,进行修改,

$ emacs ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack/bin/webpack.js

文件头部,我们require debug模块,它会返回一个log函数,
(注意要放在#!/usr/bin/env node后面。)

#!/usr/bin/env node
const log = require('debug')('debug-webpack webpack webpack.js');

3.3 写日志

使用以上返回的log函数写日志,
console.log不同的是,debug消息会自动进行颜色区分。
稍微修改下源码,

const cliPath = path.resolve(path.dirname(pkgPath), pkg.bin[installedClis[0].binName]);
log('cliPath: %s', cliPath);
require(cliPath);

3.4 debug运行

先回到webpack工程目录,然后带参数执行下webpack命令

$ cd ~/Test/debug-webpack
$ DEBUG=debug-webpack* webpack

其中DEBUG=debug-webpack*,是Shell的前缀参数,
参考:Prefix Shell Parameters

4.5 运行结果

我们会发现命令行消息中,多了一行,

debug-webpack webpack webpack.js cliPath: ~/.nvm/versions/node/v8.12.0/lib/node_modules/webpack-cli/bin/cli.js +0ms

4. 如何用vscode调试

4.1 创建 debug.js

由于webpack是使用命令行工具调用的,
vscode暂时不支持调试命令行工具,但是可以调试node.js。

因此,我们在debug-webpack工程目录建立如下文件,

const webpack = require('webpack');
const options = require('./webpack.config');

const compiler = webpack(options);

compiler.run((...args) => {
    console.log(...args);
});

之所以这样编写,是因为我们阅读了webpack命令行工具的源码,模仿它的调用方式进行调用。
cli.js 第533行
会调用compiler.run,执行实际的webpack逻辑。

} else compiler.run(compilerCallback);

4.2 打开vscode调试

保持debug.js文件打开状态,处于vscode当前的活跃标签,
然后点击vscode调试面板运行调试。(或者直接按F5)。

我们可以事先在compiler.run位置打个断点。
调试开始后,我们会发现程序停止在了断点位置。


参考

简书:Node Version Manager
简书:Prefix Shell Parameters

相关文章

网友评论

    本文标题:[FE] webpack v4.20.2 源码解析(一):准备工

    本文链接:https://www.haomeiwen.com/subject/udjyaftx.html