webpack配置从入门到放弃(2)

139 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

webpack asset资源处理

图片处理

  1. 在 index.js 中添加如下代码

    import src from "./images/1.jpg";
    import title from "./data/1.txt";
    let img = document.createElement("img");
    img.src = src;
    img.title = title;
    document.body.appendChild(img);
    
  2. 在 webpack.config.js 中添加配置

    //在output中配置图片文件的打包路径和文件名
    assetModuleFilename: "images/[name]-[hash][ext]",
    ​
    //在rules数组中配置图片
    {
    test: /.(png|jpg|jpeg|gif|svg|webp)$/,
    type: "asset",
    parser: {
        dataUrlCondition: {
            maxSize: 10 * 1024, //大于10KB的图片打包进dist目录,小于10KB的图片会转换成base64数据格式
        },
    },
    // 比assetModuleFilename优先高,就近原则
    // generator: {
    //   filename: "imgs/[name][ext]",
    // },
    },
    
  3. 终端执行 npm run build ,然后执行 npm run serve,浏览器访问 http:localhost:8080 就可以看到图片了。

字体处理

  1. 在 webpack.config.js 文件中添加配置:

    {
    test: /.(woff|woff2|eot|ttf|otf)$/i,
        type: "asset/resource",
        generator: {
            filename: "fonts/[name][ext]",
        },
    },
    

其他格式文件处理

在开发中还可能遇见各种各样格式的文件,如:csv、xml、toml、yaml、json5等等,大致配置都和上面的差不多,有的需要插件,有的需要下载 loader,在拿捏不准的时候可以在webpack官网 中查到,接下来配置一下这几种格式文件的处理。

  1. csv 和 xml 文件是 loader,终端执行 npm i csv-loader xml-loader

    //在rules数组中加入
    {
        test: /.(csv|tsv)$/i,
        use: ["csv-loader"],
    },
    {
        test: /.xml$/i,
        use: ["xml-loader"],
    },
    
  2. toml、yaml、json5文件需要下载插件,终端执行 npm i toml yaml json5

    //插件需要引入
    const toml = require('toml');
    const yaml = require('yamljs');
    const json5 = require('json5');
    ​
    //在rules数组中写入
    {
        test: /.toml$/i,
        type: "json",
        parser: {
            parse: toml.parse,
        },
    },
    {
        test: /.(yaml|yml)$/i,
        type: "json",
        parser: {
            parse: yaml.parse,
        },
    },
    {
        test: /.json5$/i,
        type: "json",
        parser: {
            parse: json5.parse,
        },
    },
    

devtool

此选项控制是否生成,以及如何生成 source map。方便开发者在开发中查看控制台信息,不同的值会明显影响到构建(build)的速度

module.exports = {
    ……原有代码……
    //源码映射
    devtool:"inline-source-map", //其他属性可以去官网了解
}

转换ES6+代码

在开发已经用了ES6+的高级方法,但是在低版本的浏览器上可能不兼容,还不能识别这些高级代码,所以要把这些高级代码转换成ES5的代码

  1. 下载需要的依赖

    babel-loader

    @babel/core

    @babel/preset-env

    @babel/plugin-transform-runtime

    @babel/polyfill

    @babel/runtime-corejs3

  2. 新建配置文件 .babelrc,添加如下配置:

    {
        "presets": [["@babel/preset-env"]],
        "plugins": [
            [
                "@babel/plugin-transform-runtime",
                {
                    "absoluteRuntime": false,
                    "corejs": 3,
                    "helpers": true,
                    "regenerator": true,
                    "useESModules": false
                }
            ]
        ]
    }
    
  3. 在 webpack.config.js 中添加如下配置:

    //使用babel将ES6+代码转换成ES5的代码
    {
        test: /.m?js$/,
        exclude: /node_modules/,
        use: {
            loader: 'babel-loader',
        }
    },
    
  4. 终端执行 npm run build,就可以看到生成的 js 文件都是ES5的代码了

代码分离

在开发过程中经常会用到第三方的库或者自己写的公共函数,这些库或函数可能在多个文件中被引入使用,在打包时每个入口文件都会加上这些库或函数的源代码,导致一个文件变得很大,造成了资源的浪费,所以要把这些库或函数单独打包出来。

代码分离方式一

在 webpack.config.js 中添加配置:

module.exports = {
    entry: {
    index: {
      import: "./src/index.js",
      dependOn: "shared", //打包后的文件名
    },
    welcome: {
      import: "./src/welcome.js",
      dependOn: "shared", //打包后的文件名
    },
    shared: ["jquery", "./src/CalcArea.js"], //需要独立打包的库或函数
  },
  ……原有代码……
}

需要自己添加独立打包的库,如果引入了很多库,就比较麻烦,而且所有库和函数都会被打包进一个文件,会让这个文件变得非常大,网络请求变得非常慢。

代码分离方式二

在 webpack.config.js 中添加配置:

//在optimization对象中
optimization{
    // splitChunks: {
    //   chunks: "all",
    //   minSize: 10, //设置能够打包的最小体积,默认是20000Bytes
    //   minChunks: 2, //打包的模块的最小引用次数,默认是1
    //   name: "vendors" //指定output中打包文件的name
    // },
​
    splitChunks: {
      //缓存组
      cacheGroups: {
        module: {
          test: /[\/]node_modules[\/]/,
          name: 'module',
          chunks: 'all',
        },
        commons: {
          test: /src/,
          name: 'vendors',
          chunks: 'all',
          minSize: 10,
        },
      },
    },
}

可以单独打包自定义的公共函数和库,在test中配置即可

代码分离方式三

在 webpack.config.js 中添加配置:

//在plugins数组中配置
plugins: [
    externalsType: "script",
    externals: {
        jquery:["https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js","$"],
    },
]

将 externals 类型设置为 'script',webpack 将会通过 HTML 中的 <script> 标签加载一个脚本,以暴露预定义的全局变量。使用CDN的方式引入jquery,数组第一个是CDN地址,第二个是引入库的别名。

代码分离方式四

第四种方式是按需加载,也成为懒加载,不需要额外配置。有两种情况:

  • prefetch(预获取):将来某些导航下可能需要的资源,在网络空闲时自动下载资源
  • preload(预加载):当前导航下可能需要资源,网络请求时下载资源

与 prefetch 指令相比,preload 指令有许多不同之处:

  • preload chunk 会在父 chunk 加载时,以并行方式开始加载。prefetch chunk 会在父 chunk 加载结束后开始加载。
  • preload chunk 具有中等优先级,并立即下载。prefetch chunk 在浏览器闲置时下载。
  • preload chunk 会在父 chunk 中立即请求,用于当下时刻。prefetch chunk 会用于未来的某个时刻。
  • 浏览器支持程度不同。

在使用只需要添加一个注释即可:

//预获取
const prefetch = () =>
  import(/* webpackPrefetch:true */ 'jquery').then((default: $) => {
      
  });
//预加载
const preload = () =>
  import(/* webpackPreload:true */ 'jquery').then((default: $) => {
      
  });