详细解析Webpack是怎么运行的

在平时开发中我们经常会用到 Webpack这个时下最流行的前端打包工具。它打包开发代码,输出能在各种浏览器运行的代码,提升了开发至发布过程的效率。

我们知道一份Webpack配置文件主要包含入口( entry)、输出文件( output)、模式、加载器( Loader)、插件( Plugin)等几个部分。但如果只需要组织 JS 文件的话,指定入口和输出文件路径即可完成一个迷你项目的打包。下面我们来通过一个简单的项目来看一下Webpack是怎样运行的。

同步加载

本文使用 webpack ^4.30.0 作示例.为了更好地观察产出的文件,我们将模式设置为 development 关闭代码压缩,再开启 source-map 支持原始源代码调试。除此之外。我们还简单的写了一个插件 MyPlugin来去除源码中的注释。

新建 src/index.js:

console.log('Hello webpack!');

新建 webpack配置文件 webpack.config.js

const path = require('path');
const MyPlugin = require('./src/MyPlugin.js')
module.exports = {
 mode: 'development',
 devtool: 'source-map',
 entry: './src/index.js',
 output: {
 path: path.resolve(__dirname, 'dist')
 },
 plugins:[
 new MyPlugin()
 ]
};

新建 src/MyPlugin.js。了解webpack插件更多信息

class MyPlugin {
 constructor(options) {
 this.options = options
 this.externalModules = {}
 }
 apply(compiler) {
 var reg = /("([^\\\"]*(\\.)?)*")|('([^\\\']*(\\.)?)*')|(\/{2,}.*?(\r|\n))|(\/\*(\n|.)*?\*\/)|(\/\*\*\*\*\*\*\/)/g
 compiler.hooks.emit.tap('CodeBeautify', (compilation)=> {
  Object.keys(compilation.assets).forEach((data)=> {
  let content = compilation.assets[data].source() // 欲处理的文本
  content = content.replace(reg, function (word) { // 去除注释后的文本
   return /^\/{2,}/.test(word) || /^\/\*!/.test(word) || /^\/\*{3,}\//.test(word) ? "" : word;
  });
  compilation.assets[data] = {
   source(){
   return content
   },
   size(){
   return content.length
   }
  }
  })
 })
 }
}
module.exports = MyPlugin

现在我们运行命令 webpack --config webpack.config.js ,打包完成后会多出一个输出目录 dist:dist/main.js。main 是 webpack 默认设置的输出文件名,我们快速瞄一眼这个文件:

(function(modules){
 // ...
})({
 "./src/index.js": (function(){
 // ...
 })
});

整个文件只含一个立即执行函数(IIFE),我们称它为 webpackBootstrap,它仅接收一个对象 —— 未加载的 模块集合(modules),这个modules 对象的 key 是一个路径,value 是一个函数。你也许会问,这里的模块是什么?它们又是如何加载的呢?

在细看产出代码前,我们先丰富一下源代码:

新文件 src/utils/math.js:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/1508.html