前端模块打包工具

147 阅读3分钟

CommonJS与ES6 Moudule最本质的区别在于前者模块依赖关系的建立发生在代码运行阶段,后者模块依赖关系的建立发生在代码编译阶段。

CommonJS与ES6 Moudule区别:

  1. 前者建立模块依赖关系是在运行时,后者是在编译时;
  2. ES6 Module通过其静态特性可以进行编译过程中的优化,并且具备处理循环依赖的能力;
  3. 值拷贝与动态映射: 在导入一个模块时,对于CommmonJS来说获取的是一份导出值的拷贝,而在ES6 Module中则是值的动态映射,并且这个映射是只读的;

ES6 Module与CommonJS优势:

  1. 死代码检测和排除。我们可以用静态分析工具检测出哪些模块没有被调用。
  2. 模块变量类型检查。JavaScript属于动态类型语言,不会在代码执行前执行检查类型错误。ES6 Module的静态模块结构有助于确保模块之前传递的值或接口类型是正确的。
  3. 编译器优化。在CommonJS等动态模块系统中,无论采用哪种方式,本质上导入的都是一个对象,而ES6 Module支持直接导入变量,减少了引用层级,程序效率更高。

AMD 异步模块定义:

它与CommonJS和ES6 Moudle最大区别在于它加载模块的方式是异步的

define('getSum', ['calculator'], function(math) {
    return function(a, b) {
        console.log('sum: ' + calculator.add(a, b));
    }
})

第1个参数是当前模块的id,相当于模块名;第2个参数是当前模块的依赖,第3个参数用来描述模块的导出值,如果是函数则导出的是函数的返回值;如果是对象则直接导出对象本身。

UMD 通用模块标准:

严格来说,UMD并不能说是一种模块标准,不如说它是一组模块形式的集合更准确。它的目标是使一个模块能运行在各种环境下,不论是CommonJS、AMD,还是非模块化的环境。

webpack资源处理流程

entry、chunk、bundle的关系:

1.chunk: 从entry开始这些存在依赖关系的模块会在打包时被封装为一个chunk;

2.bundle: webpack会从入口文件开始检索,并将具有依赖关系的模块生成一颗依赖树,最终得到一个chunk。由这个chunk得到的打包产物我们一般称之为bundle。 截屏2022-01-24 下午3.21.05.png

webpack配置资源入口

Webpack通过context和entry这两个配置项来共同决定入口文件的路径。

1.context: 可以理解为资源入口的路径前缀;

module.exports = {
   context: path.join(__dirname, './src/scripts'),
   entry: './index.js',
}

2.entry: entry的配置可以有多种形式:字符串、数组、对象、函数。

1. 字符串类型入口
enty: './src/index.js'

2. 数组类型入口: 传入一个数组的作用是将多个资源预先合并,在打包时webpack会将数组中的最后一个元素作为实际的入口路径
entry: ['babel-polyfill', './src/index.js']

3.对象类型入口
entry: {
    index: './src/index.js',
    lib: './src/lib.js'
}

4.函数类型入口: 只要返回上面介绍的任何配置形式即可
entry: () => './src/index.js'
entry: () => new Promise((resolve) => {
    setTimeout(() => {
        resolve('./src/index.js');
    }, 1000);
})

3.提取vendor(供应商)

在webpack中的vendor一般指的是工程所使用的库、框架等第三方模块集中打包而产生的bundle。之后再配置optimization.splitChunks,将他们从各个页面中提取出来,生成单独的bundle即可。

module.exports = {
    context: path.join(__dirname, './src'),
    entry: {
        app: './src/app.js',
        vendor: ['react', 'react-dom', 'react-router'],
    },
}

webpack配置资源出口

截屏2022-01-24 下午5.20.51.png

1.filename的作用是控制输出资源的文件名,可以是字符串和相对路径

filename: 'bundle.js'
filename: './js/bundle.js'

截屏2022-01-24 下午5.36.19.png

2.publicPath用来指定资源的请求位置。

  • HTML相关 截屏2022-01-24 下午8.36.57.png

  • Host相关 截屏2022-01-24 下午8.38.03.png

  • CDN相关 截屏2022-01-24 下午8.38.47.png