美文网首页
webpack 基本概念与配置

webpack 基本概念与配置

作者: jluemmmm | 来源:发表于2020-12-14 22:03 被阅读0次

webpack 是一个 js 静态模块打包器,webpack 处理应用程序时,会递归构建一个依赖关系图,其中包含应用程序需要的每个模块,将所有这些模块打包成一个或多个 bundle。

概念 功能
entry 1. 告诉 webpack 应该使用哪个模块,作为构建其内部依赖的开始,默认为./src
2. 进入入口起点后,webpack会找出哪些模块是入口起点直接或间接依赖的;
3.每个依赖项被处理,输出到称为 bundle 的文件中;
output 告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为./dist
loader 1. webpack 自身只理解 js,loader 可将所有类型的文件转换为 webpack 能处理的有效模块;
2. test 属性标识出应被对应 loader 转换的文件,use 标识进行转换时,应该使用的 loader
plugins 1. 从打包优化、压缩、重新定义环境中的变量的处理;
2. 插件使用时,将其添加到plugin数组中,多数插件可以通过option自定义,在一个配置文件中多次使用一个插件时,需要通过new操作符创建实例

webpack.config.js

const config = {
  /*---- ENTRY ----*/
  /* 单个入口写法  entry: string | Array<string> */
  /* 字符串 */
  entry: './src/index.js'
  /* 对象 */
  entry: {
    main: './src/index.js'
  }
  /* 向 entry 传入 [文件路径数组] 时, 将创建多个主入口, 适用于将多个依赖文件一起注入, 且将他们呢的依赖导向到一个 chunk 的场景 */

  entry: [
    './src/file_1.js',
    './src/file_2.js'
  ],
  output: {
    filename: 'bundle.js'
  }

  /* 对象语法 */

  /* 分离 app 和 vendor 入口 */
  /* 这样做的目的: 在 vendor.js 中导入未修改的库或文件, 如 Bootstrap, jquery, 图片等, 将他们
   * 打包在一起成为自己的 chunk, content hash 保持不变, 使浏览器可以分别缓存他们, 减少加载时间。

   * - webpack version < 4 时, 通常添加 vendors 作为 entry 的一个设置项, 将其编译为单独的文件。
   * 通常与 CommonsChunkPlugin 结合使用 https://www.webpackjs.com/plugins/commons-chunk-plugin;
   * 
   * - 在 webpack 4 中不建议这样做, optimization.splitChunks 选项用于分离 vendors 和 app modules,
   * 并且用于创建独立的文件, 不要为不是执行的入口节点的 vendors 或 stuff 创建 entry*/

  entry: { /* webpack.config.js */
    main: './src/app.js',
    vendor/* adminApp */: './src/vendor.js'
  }
  output: { /* webpack.prod.js */
    filename: '[name].[contenthash].bundle.js',
  }
  output: { /* webpack.dev.js */
    filename: '[name].bundle.js'
  }

  /* 多页应用: 告诉 webpack 需要三个独立分离的依赖图
   * 多页应用中, 服务器将会获取一个新的 html 文档, 页面重新加载文档, 并且资源被重新下载。
   * - webpack version < 4 时, 使用 CommonsChunkPlugin 为每个页面间的应用程序共享代码创建 bundle, 
   * 多页应用能够复用入口起点之间的模块代码;
   * - webpack version 4, 使用 optimization.splitChunks 为页面间的共享代码创建 bundle. */
  entry : {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }

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

  /* 单个入口起点 */
  output: {
    filename: 'bundle.js', /* 输出文件的文件名 */
    path: '/home/public/assets' /* 目标输出 path 的绝对路径 */
  }

  /* 多个入口起点, 如果配置创建了多个 chunk, 如使用多个入口起点或使用像 CommonsChunkPlugin 这样的插件,
   * 需要使用占位符确保每个文件具有唯一的名称 */
  entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: '[name.js]',
    path: __dianame + './dist' /* 写入到硬盘 ./dist/app.js 和 ./dist/search.js */
  }

  /* 使用 CDN 和资源 hash 示例 */
  output: {
    path: '/home/cdn/assets/[hash]',
    publicPath: 'http://cdn.example.com/assets/[hash]'
  }

  /*  在编译时不知道最终输出文件的 publicPath 的情况下, publicPath 可以留空, 并在入口起点文件运行时动态设置 */
  __webpack_public_path__ = myRuntimePublicPath


  /*------LOADER------- */
  /* loader 用于对模块的源代码进行转换, loader 可以使得在加载时预处理文件。使用 loader 的三种方式:
   * 1. 配置, 在 webpack 配置中指定多个 webpack.config.js 文件中指定 loader
   * 2. 内联, 在 import 语句中显示指定 loader
   * 3. cli, 在 shell 命令中指定多个loader 
   */

   /* loader 特性: 
    * 1. 支持链式传递, 一组链式的 loader 按照相反的顺序执行, loader 链中的第一个 loader 返回值给下一个 loader, 在
    *     最后一个 loader, 返回 webpack 所预期的 js
    * 2. 可以同步, 也可以异步
    * 3. 运行在 nodejs 中, 执行任何可能的操作
    * 4. 接收查询参数或通过options 对象进行配置
    * 5. 普通 npm 导出 loader 方式:package.json 定义 loader 字段 
    * 6. loader 遵循标准的模块解析, 从模块路径 npm install node_modules 解析
    * 7. loader 模块导出为一个函数, 通常使用 npm 进行管理, 可以将自定义 loader 作为应用程序中的文件
    *    编写一个 loader https://www.webpackjs.com/contribute/writing-a-loader/
    */

  module: {
    rules: [ /* use 后面可以跟字符串形式的 loader, 也可以跟数组 */
      { test: /\.ts$/, use: 'ts-loader'},
      { test: /\.css$/, use: [
        { loader: 'style-loader' },
        { 
          loader: 'css-loader',
          options: { modules: true }
        },
        { loader: 'sass-loader' }
      ]}
    ]
  }

  /* ----PLUGIN------- */
  /* plugin 用在 webpack 打包编译过程中, 在对应的事件节点里执行自定义操作, 如资源管理\bundle 文件优化等操作
   * webpack 中 loader 和 plugin 的区别是什么 https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/308
   * 
   * 在插件中使用 webpack-sources 时, 使用 require('webpack').sources, 而不是 require(webpack-sources) 避免持久缓存的版本冲突
   * 
   * webpack 插件是具有 apply 属性的 js 对象, apply 属性会被 webpack compiler 调用, compiler 对象可在整个编译生命周期访问
   */

  const pluginName = 'ConsoleLogOnBuildWebpackPlugin'
  class ConsoleLogOnBuildWebpackPlugin {
    apply(compiler) { /* tap 方法的第一个参数, 是驼峰式命名的插件名称, 建议使用一个常量, 以便在所有 hook 中复用 */
      compiler.hooks.run.tap(pluginName, compilation => {
        console.log('webpack 构建过程开始')
      })
    }
  }

  /* 插件可以携带参数/选项, 在 webpack 配置中, 向 plugins 属性传入 new 实例*/
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HTMLWebpackPlugin({ template: './src/index.html'})
  ]

}

module.exports = config

相关文章

网友评论

      本文标题:webpack 基本概念与配置

      本文链接:https://www.haomeiwen.com/subject/mzabwktx.html