以前每件事都差很少,直到如今才发现差不少。如今才发现理清一件事的原委是多么快乐的一件事,咱们共同勉励。javascript
懒得扯淡,直接正题css
不基于例子的讲原理都是扯淡,知乎同样的举例都是卖弄html
要说如今的模块打包确定用的最多的就是webpack,下面由浅入深的讲一下它的原理,在这里举例打包js和css模块。java
ps: 基于webpack 4node
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'] }] } };
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>webpack-learn</title> </head> <body> <div class="wrapper">webpack-learn</div> </body> </html>
.wrapper { font-size: 20px; color: #f00; }
// 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
$ webpack
查看 dist/js/index.[chunkhash:4].js 文件,发现文件有点大,不知道从何处看起,那么咱们把入口js文件进行剥茧抽丝,清空,看一下,最简单的打包后的文件。web
/******/ (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在打包时作了模块依赖的解析和深度遍历模块的依赖
bash