美文网首页
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