美文网首页
阅读《深入浅出Webpack》和官方文档 -- 基础

阅读《深入浅出Webpack》和官方文档 -- 基础

作者: Pretty_Boy | 来源:发表于2019-05-03 20:56 被阅读0次

    基础

    1. 模块化

    CommonJS: 用于Node.js环境

    // 导出
    module.exports = moduleA.func;
    // 导入
    const moduleA = require( url );
    

    AMD: 用于Node.js环境,浏览器。异步方式家在模块 -> requirejs

    // 定义模块
    define( 'module', ['dep'], function(dep) {
      return exports;
    } )
    // 导入模块
    require( ['module'], function(module) {} )
    

    ES6模块化: 需要转化成es5运行

    // 导出
    export function  hello(){};
    export default {};
    // 导入
    import { A } from url;
    import B from url;
    

    一直计划说详细学一下webpack,然后由于各种因素拖到了现在。 结合《深入浅出Webpack》和官方文档。

    概念: 静态模块打包器(module bundler), 将从入口开始 构建整个应用的依赖关系图,然后将所有模块打包成一个或者多个bundle。

    • 入口(entry): 应用从哪个文件作为依赖图的开始。
    • 出口(output): 在哪里输出根据依赖图所创建的bundles, 以及如何命名这些文件。【默认为./dist】
    • 插件(plugins): loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。
    • 模式(mode): 可以启用响应模式下的webpack内置的优化(development, production)
    • Chunk: 一个chunk由多个模块组成, 用于代码合并与分割。
    • module: 处理模块的规则
    • resolve:寻找模块的规则

    1. Entry: 可配置 多页面应用 或者 多入口的单页应用

    const config = {
      entry: './path/to/my/entry/file.js'   // string 类型
    };
    const config = {
      entry: ['./path/to/my/entry/file1.js', './path/to/my/entry/file2.js']   // array 类型  
      // 数组里的最后一个入口文件的模块会被导出。
    };
    const config = {
      entry: {  // object 类型
          pc:  './pc/pc.js',
          h5:  './h5/h5.js',
      } 
    };
    

    2. Output:

     const config = {
      output: {
        filename: "",  // string 类型
        chunkFilename: "", // string  需要在runtime根据chunk发送的请求去生成
        path: path.resolve(__dirname, 'dist/assets'),
        publicPath: "", // 静态资源的路径。 需要按照开发环境或者生产环境配置
        library:"", // string 导出库的名称
        libraryTarget: "",  // enum  已何种方式导出库
        libraryExport: "", // string, array 导出那些子模块
      }
    };
    

    内置变量列表:

    1. id: Chunk的唯一标识, 从0开始
    2. name: Chunk的名称
    3. hash:Chunk的唯一标识的Hash值
    4. chunkhash: Chunk内容的Hash值
    5. query 模块文件名 ? 后面的字符串
      注: Hash的长度是可以指定的如:[hash:8] ,默认20
      其他配置项 在官方文档中有介绍或者后续的笔记中更新。

    3. Module: 如何处理不同类型的模块

     const config = {
      module: {
        noParse: /jquery/ ,  // 忽略部分文件的解析和处理( 被忽略的文件不该包含import, require, define)
        rules: [  // 配置Loader
          {
            test: /\.css/,   //  正则表达式的匹配规则, 也可是个array
            use: [],  // 数组中可以是string, object
            enforce: "pre", // enum  ["pre", "post"] 
            include: path.resolve(__dirname, 'src'),// 仅匹配src目录中的文件
            exclude: path.resolve(__dirname, 'dist'),// 排除dist目录中的文件
            and: [],  // 必须匹配所有条件
            or: [],
            not: [],
          }
        ],
        parser: {  // 指定解析器的开关, 精确控制哪些语法可以被解析
           amd: false,
           commonjs: true,
        }   
      }
    };
    

    其中当use中,设置为对象时, 可以向其loader传入多个参数

      use: [
        {
          loader: "",  //  所使用的loader
          options: {},  // 向loader传入的参数
        }
      ]
    

    使用oneOf,对匹配规则进行嵌套,

        rules: [  // 配置Loader
          {
            test:  /\.css/,
            oneOf: [ // 可以指定嵌套规则
              {
                resourceQuery: /inline/, // foo.css?inline
                use: 'url-loader'
              },
              {
                resourceQuery: /external/, // foo.css?external
                use: 'file-loader'
              }
            ], 
          }
        ]
    

    配置loader 通过一下方式完成:

    1. 条件匹配: 通过test,include,exclude
    2. 应用规则: 通过use应用loader
    3. 重置顺序: 默认loader的顺序是从右向左的, 使用enforce选项将loader的执行顺序改变

    webpack自带的loader库

    4. Resolve: 模块如何被解析, (webpack本身含有默认值)

    const config = {
      resolve: {
        alias: { // 创建别名。 使引用是更方便,避免过多的相对路径
          images: path.resolve(__dirname, 'src/images/')
          css$: path.resolve(__dirname, 'src/assets/css')  // $ 标识精准匹配
        },
        extensions: [".js",".json"], // 当无后缀名时,默认自动带上后缀解析
        mainFiles: [], // 指定导入模块时 导入的哪部分代码
        modules: ["node_modules"], // 默认只去node_modules中寻找第三方模块
        enforceExtension: false, // 允许无扩展名文件的引用
        unsafeCache: /\aa/, // 开启仅缓存aa模块  regex, array, boolean
        plugins: [],  // 额外的解析插件列表
      }
    }
    

    mainFiles, 默认为["browser", "module", "main"], 默认顺序
    在其他target时, 默认为["module","main"]
    即 对应 所引用包的package.json中的

    {
      main: "build/d3.Node.js",
      browser: "build/d3.js",
      module: "index",
    }
    

    5. Plugins

    const config = {
     plugins: [ // array
         // 每项是一个插件的实例, 将参数通过构造函数传入
         new CommonsChunkPlugin({  // 将所有公共代码提取到common代码块中
           name: "common",
           chunks: ["a","b"]
         })
     ]
    }
    

    Webpack自带的插件库

    6. DevServer: 在开发中的行为

    const config = {
     devServer: {
       host: "", // 默认为localhost, 设置为ip 供外部访问
       port: "", // 监听的端口, 默认8080
       inline: true,  // false 时 责启用iframe模式, true为嵌入bundle中
       allowedHosts: [], // 设置白名单
       compress: true, //  启用gzip压缩
       contentBase: path.join(__dirname, "public"), // 从哪提取静态文件, 默认当前执行的目录 ./
       disableHostCheck: false,  // 关闭host检查,使其他设备也能访问本地服务
       lazy: true, // 开启惰性模式,仅在请求时编译,即不监听文件改动
       filename: "", // 只在请求该文件时编译, 必须开启惰性模式
       headers: {},  // 在所有想用中添加首部内容
       hot: true, // 开启模块热替换,仅刷新改变的模块
       clientLogLevel: "info",  // enum 客户端的日志级别,默认info
       https: true, // 默认使用http服务,开启https 后自动生成一份证书,也可用{}配置自己的证书,读文件
       open: true,  // 第一次构建后 自动打开浏览器
       proxy: {
         "/api":  "http://localhost:3000",
         "/users": {
           target: "https://localhost:3000",
           pathRewrite: {"^/users" : ""},  // 将路径重写 如 /users/login -> /login
           secure: false, // 若代理到https服务,则需要将secure设为false
           bypass: function(req, res, proxyOptions) {
             if (req.headers.accept.indexOf("html") !== -1) {
               console.log("Skipping proxy for browser request.");
               return "/index.html";
             }
           }
         }
       },
       quiet:  true, // 除初始启动信息外都不会打印到控制台
     }
    }
    
      proxy: [{  // 针对多个请求 进行代理
        context: ["/auth", "/api"],
        target: "http://localhost:3000",
      }]
    

    7. Devtool:配置source map

    const config = {
      devtool: "none" // 构建source-map方便调试  enum 
    }
    

    具体的选项和构建速度 在官方文档中有详细的表格

    8. Target:配置source map

    const config = {
      target: "web",  // enum 默认web, 还有node,webworker, electron等  
    
    const webpack = require("webpack");
    
    const options = {
      target: (compiler) => {  // function  使用非自带的target的插件
        compiler.apply(
          new webpack.JsonpTemplatePlugin(options.output),
          new webpack.LoaderTargetPlugin("web")
        );
      }
    };
    

    9. Watch: 监听规则

    const config = {
      watch: true, //  默认false, 在devServer中默认开启
      watchOptions: {
        ignored: /node_modules/,  // 或者使用"files/**/*.js" 这种形式
        poll: 1000, // number, boolean 每秒进行轮询
        aggregateTimeout: 300, // 监听到变化后 延迟300ms再执行
      }
    }
    

    10. Externals不打包某些模块

    const config = {
      externals: {
        jquery: 'jQuery'  //  string, array. object, function, regex
      }
    }
    

    因为全局引入了一些模块或变量,然后import的时候,会使webpack将模块再打包一次,所以会出现重复的内容,使用externals排除在外。

    11. Performance

    const config = {
      performance: {
        hints: "warning",  //  打开提示,在开发环境使用warning,生产error
        maxEntrypointSize: 400000, //  根据入口起点的最大体积,控制 webpack 何时生成性能提示  默认值 250000 bytes
        maxAssetSize: 100000, // 根据单个资源体积,控制 webpack 何时生成性能提示
        assetFilter: function(assetFilename) {  // 只给出 .js 文件的性能提示。
          return assetFilename.endsWith('.js');
        }
      }
    }
    

    12. Stats

    stats: "minimal", // string  enum  只在发生错误或有新的编译时输出
    stats: {}, // 使用对象对统计信息 进行更精确的控制
    

    至此 ,文档中的概念,配置,Loaders, plugins 已完成概览。接下来抽空完成,实战, 优化, 原理。

    相关文章

      网友评论

          本文标题:阅读《深入浅出Webpack》和官方文档 -- 基础

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