【webpack篇】原理
之前每件事都差不多,直到现在才发现差很多。现在才发现理清一件事的原委是多么快乐的一件事,我们共同勉励。
懒得扯淡,直接正题
不基于例子的讲原理都是扯淡,知乎一样的举例都是卖弄
要说现在的模块打包肯定用的最多的就是webpack,下面由浅入深的讲一下它的原理,在这里举例打包js和css模块。
ps: 基于webpack 4
打包构建解析
示例环境依赖及部分代码
依赖
- "clean-webpack-plugin": "^0.1.18",
- "css-loader": "^0.28.10",
- "html-webpack-plugin": "^3.0.4",
- "style-loader": "^0.20.2",
- "webpack": "^4.0.1",
- "webpack-cli": "^2.0.10"
webpack.config.js
const path = require('path');
const webpack = require('webpack');
//用于插入html模板
const HtmlWebpackPlugin = require('html-webpack-plugin');
//清除输出目录,免得每次手动删除
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
mode: 'development',
entry: {
index: path.join(__dirname, 'index.js'),
},
output: {
path: path.join(__dirname, '/dist'),
filename: 'js/[name].[chunkhash:4].js'
},
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
})
],
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
}
};
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack-learn</title>
</head>
<body>
<div class="wrapper">webpack-learn</div>
</body>
</html>
index.css
.wrapper {
font-size: 20px;
color: #f00;
}
js 文件
// index.js
const test = require('./src/js/test');
require('./src/css/index.css');
console.log(test);
// test.js
const str = 'test is loaded';
module.exports = str;
页面结构如下:
运行
$ webpack
打包结果分析
查看 dist/js/index.[chunkhash:4].js 文件,发现文件有点大,不知道从何处看起,那么我们把入口js文件进行剥茧抽丝,清空,看一下,最简单的打包后的文件。
/******/ (function(modules) { // webpackBootstrap
/******/ var installedModules = {};
/******/ function __webpack_require__(moduleId) {
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ module.l = true;
/******/ return module.exports;
/******/ }
/******/ __webpack_require__.m = modules;
/******/ __webpack_require__.c = installedModules;
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/ __webpack_require__.r = function(exports) {
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/ __webpack_require__.p = "";
/******/ return __webpack_require__(__webpack_require__.s = "./index.js");
/******/ })
/******/ ({
/***/ "./index.js":
/***/ (function(module, exports) {
eval("//# sourceURL=webpack:///./index.js?");
/***/ })
/******/ });
发觉其打包产出是一个FFII,参数为由模块名和模块文件处理成的函数组成的对象,由此,我们可以猜测 webpack在打包时做了模块文件到函数的转换
。我们再把入口文件内容恢复,再看一下打包结果的FFII参数。
除了 src/js/test.js 和 src/css/index.css 模块以外还有 node_modules 里面的 css-loader 和 style-loader。由此,我们可以猜测 webpack在打包时做了模块依赖的解析和深度遍历模块的依赖
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。