webpack总结

configuration

  • webpack 的配置文件,是导出一个对象的 JavaScript 文件
  • 因为 webpack 配置是标准的 Node.js CommonJS 模块,你可以做到以下事情:
    • 通过 require(...) 导入其他文件
    • 使用 JavaScript 控制流表达式,例如 ?: 操作符
    • 对常用值使用常量或变量
    • 编写并执行函数来生成部分配置

entry

  • 入口起点:指示webpack应该使用哪个模块来作为构建其内部依赖图的开始
  • 每个HTML页面都有一个入口起点
  • 单页面应用(SPA):一个入口起点,多页面应用(MPA):多个入口起点
  • 动态加载模块不是入口起点

output

  • 配置 output 选项可以控制 webpack 如何向硬盘写入编译文件;注意,即使可以存在多个入口起点,但只指定一个输出配置

  • 多个入口起点:

    如果配置创建了多个单独的 "chunk"(例如,使用多个入口起点或使用像 CommonsChunkPlugin 这样的插件),则应该使用占位符(substitutions)来确保每个文件具有唯一的名称
    ```
    {
    entry: {
    app: './src/app.js',
    search: './src/search.js'
    },
    output: {
    filename: '[name].js',
    path: __dirname + '/dist'
    }
    }

    // 写入到硬盘:./dist/app.js, ./dist/search.js

loader

  • loader 让webpack有能力处理那些非JavaScript文件(webpack 自身只理解JavaScript )[转换某些类型的模块]
  • test属性:标识出应该被对应loader进行转换的某些或某个文件
  • use:进行转换时应该使用哪个loader
  • loader 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript

plugin

  • 插件目的在于解决 loader 无法实现的其他事
  • 插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量
  • 使用:首先通过require()导入,然后将它添加到plugins数组中;当在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例
  • 由于插件可以携带参数/选项,你必须在 webpack 配置中,向 plugins 属性传入 new 实例。
  • 多数插件可以通过选项(option)来配置

file loader

即使含有 jsx的语法的文件后缀是jswebpack 在加载文件时 test 的正则表达式依然要包含 jsx

publicPath

确保 publicPath 总是以斜杆( / )开头和结尾

CommonsChunkPlugin

从应用程序bundle中提取vendor引用到vendor bundle,并把引用vendor的部分替换为 __webpack__require()调用

module resolution

  • resolver 是一个库(library),用于帮助找到模块的绝对路径
  • 解析器(resolver)将检查路径是否指向文件或目录。如果路径指向一个文件:
    • 如果路径具有文件扩展名,则被直接将文件打包
    • 否则,将使用 [resolve.extensions] 选项作为文件扩展名来解析,此选项告诉解析器在解析中能够接受哪些扩展名(例如 .js, .jsx)
  • 如果路径指向一个文件夹,则采取以下步骤找到具有正确扩展名的正确文件:
    • 如果文件夹中包含 package.json 文件,则按照顺序查找 resolve.mainFields 配置选项中指定的字段。并且 package.json 中的第一个这样的字段确定文件路径
    • 如果 package.json 文件不存在或者 package.json 文件中的 main 字段没有返回一个有效路径,则按照顺序查找 resolve.mainFiles 配置选项中指定的文件名,看是否能在 import/require 目录下匹配到一个存在的文件名
    • 文件扩展名通过 resolve.extensions 选项采用类似的方法进行解析
  • resolve.alias: 替换初始模块路径,来确保模块引入变得更简单; 例如一些位于 src/ 文件夹下的常用模块:
    alias: {
      Utilities: path.resolve(__dirname, 'src/utilities/'),
      Templates: path.resolve(__dirname, 'src/templates/')
    }
    

output.filename

  • 决定了每个输出 bundle 的名称
  • 对于单个入口起点,filename 会是一个静态名称
    filename: "bundle.js"
    
  • 然而,当通过多个入口起点(entry point)、代码拆分(code splitting)或各种插件(plugin)创建多个 bundle,应该使用以下一种替换方式,来赋予每个 bundle 一个唯一的名称
    • 使用入口名称:
    filename: "[name].bundle.js"
    
    • 使用内部 chunk id
    filename: "[id].bundle.js"
    
    • 使用每次构建过程中,唯一的 hash 生成
    filename: "[name].[hash].bundle.js"
    
    • 使用基于每个 chunk 内容的 hash:
    filename: "[chunkhash].bundle.js"
    

output.chunkFileName

  • 此选项决定了非入口(non-entry) chunk 文件的名称

CommonsChunkPlugin

  • 通过将公共模块(chunk)拆出来,最终合成的文件(另一个chunk)能够在最开始的时候加载一次,便缓存到缓存中供后续使用

  • 配置:

    {
        name: string, // or
        names: string[],
        // 这是 common chunk 的名称。已经存在的 chunk 可以通过传入一个已存在的 chunk 名称而被选择。
        // 如果一个字符串数组被传入,这相当于插件针对每个 chunk 名被多次调用
        // 如果该选项被忽略,同时 `options.async` 或者 `options.children` 被设置,所有的 chunk 都会被使用,
        // 否则 `options.filename` 会用于作为 chunk 名。
        // When using `options.async` to create common chunks from other async chunks you must specify an entry-point
        // chunk name here instead of omitting the `option.name`.
    
        filename: string,
        // common chunk 的文件名模板。可以包含与 `output.filename` 相同的占位符。
        // 如果被忽略,原本的文件名不会被修改(通常是 `output.filename` 或者 `output.chunkFilename`)。
        // This option is not permitted if you're using `options.async` as well, see below for more details.
    
        minChunks: number|Infinity|function(module, count) => boolean,
        // 在传入  公共chunk(commons chunk) 之前所需要包含的最少数量的 chunks 。
        // 数量必须大于等于2,或者少于等于 chunks的数量
        // 传入 `Infinity` 会马上生成 公共chunk,但里面没有模块。
        // 你可以传入一个 `function` ,以添加定制的逻辑(默认是 chunk 的数量)
    
        chunks: string[],
        // 通过 chunk name 去选择 chunks 的来源。chunk 必须是  公共chunk 的子模块。
        // 如果被忽略,所有的,所有的 入口chunk (entry chunk) 都会被选择。
    
        children: boolean,
        // 如果设置为 `true`,所有公共 chunk 的子模块都会被选择
    
        deepChildren: boolean,
        // 如果设置为 `true`,所有公共 chunk 的后代模块都会被选择
    
        async: boolean|string,
        // 如果设置为 `true`,一个异步的  公共chunk 会作为 `options.name` 的子模块,和 `options.chunks` 的兄弟模块被创建。
        // 它会与 `options.chunks` 并行被加载。
        // Instead of using `option.filename`, it is possible to change the name of the output file by providing
        // the desired string here instead of `true`.
    
        minSize: number,
        // 在 公共chunk 被创建立之前,所有 公共模块 (common module) 的最少大小。
    }
    
  • 给 minChunks 配置传入函数:

    你也可以给 minChunks 传入一个函数。这个函数会被 CommonsChunkPlugin 插件回调,并且调用函数时会传入 module 和 count 参数;

    module 参数代表每个 chunks 里的模块, 这些 chunks 是通过 name/names 参数传入的( 传入的chunk是没有被拆出来之前的公共模块; 配置中 name/names 字段的说明: 这是 common chunk 的名称。已经存在的 chunk 可以通过传入一个已存在的 chunk 名称而被选择)
    module 有两个有用的属性:
    + module.context:这个公共模块所在的目录,例如:'/my_project/node_modules/example-dependency'
    + module.resource: 这个公共模块的文件名,例如:'/my_project/node_modules/example-dependency/index.js'
    > count 参数表示 module 被使用的 chunk 数量

    当你想要对 CommonsChunk 如何决定模块被打包到哪里的算法有更为细致的控制, 这个配置就会非常有用
    new webpack.optimize.CommonsChunkPlugin({ name: 'my-single-lib-chunk', filename: 'my-single-lib-chunk.js', minChunks: function(module, count) { // 如果模块是一个路径,而且在路径中有 "somelib" 这个名字出现, // 而且它还被三个不同的 chunks/入口chunk 所使用,那请将它拆分到 // 另一个分开的 chunk 中,chunk 的 keyname 是 "my-single-lib-chunk",而文件名是 "my-single-lib-chunk.js" return module.resource && (/somelib/).test(module.resource) && count === 3; } });
    > 正如上面看到的,这个例子允许你只将其中一个库移到一个分开的文件当中,当而仅当函数中的所有条件都被满足了

Manifest file

  • 当编译器(compiler)开始执行、解析和映射应用程序时,它会保留所有模块的详细要点。这个数据集合称为 "Manifest",当完成打包并发送到浏览器时,会在运行时通过 Manifest 来解析和加载模块
  • 分离manifest:将webpack的bootstrap(启动)逻辑提取到一个单独的文件中:
    new webpack.optimize.CommonsChunkPlugin({
      name: 'manifest',
      minChunks: Infinity
    });
    

推荐阅读更多精彩内容

  • webpack 介绍 webpack 是什么 为什么引入新的打包工具 webpack 核心思想 webpack 安...
    yxsGert阅读 5,618评论 2 72
  • 版权声明:本文为博主原创文章,未经博主允许不得转载。 webpack介绍和使用 一、webpack介绍 1、由来 ...
    it筱竹阅读 8,025评论 0 21
  • GitChat技术杂谈 前言 本文较长,为了节省你的阅读时间,在文前列写作思路如下: 什么是 webpack,它要...
    萧玄辞阅读 11,441评论 7 109
  • 记得2004年的时候,互联网开发就是做网页,那时也没有前端和后端的区分,有时一个网站就是一些纯静态的html,通过...
    阳阳阳一堆阳阅读 2,597评论 0 5
  • 第三方的canvas库 konvaJS https://konvajs.github.io/ 通用 echar...
    丶Arrow阅读 412评论 1 0