Skip to content

其他细节配置

[TOC]

context

js
context: path.resolve(__dirname, "app")//需要一个绝对路径

该配置会影响入口和loaders的解析,入口和loaders的相对路径会以context的配置作为基准路径,这样,你的配置会独立于CWD(current working directory 当前执行路径)

js
const path = require("path");

module.exports = {
  mode: "development",
  devtool: "source-map",
  //指定了context后,这里就可以省略./src了
  entry: {
    index: "./index.js",
    a: "./a.js",
  },
  //指定入口文件的根目录,相当于配置路径别名的@,webpack编译的时候会从指定的这里去寻找入口文件
  context: path.resolve(__dirname, "src"),
};

output

library

js
library: "abc"

这样一来,打包后的结果中,会将自执行函数的执行结果暴露给abc

libraryTarget

js
libraryTarget: "var"

该配置可以更加精细的控制如何暴露入口包的导出结果

其他可用的值有:

js
module.exports = {
  mode: "development",
  devtool: "source-map",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name]-[chunkhash:5].js",
    library: "abc", //将打包后的结果赋值给abc
    libraryTarget: "var", //指定打包后的赋值的模块类型
  },
};

打包后的结果

js
//将打包后的结果赋值给abc,通常是在写库的时候使用,例如Jquery,就是将打包后的结果赋值给了$
var abc =(function(){
    xxx
})()

target

js
target:"web" //默认值

设置打包结果最终要运行的环境,常用值有

js
module.exports = {
  mode: "development",
  devtool: "source-map",
  target: "node", //设置打包结果最终要运行的环境为node
};

//target的作用解析:

/*index.js
const fs=require("fs");
*/

//这个时候target配置项如果为web,那么webpack打包的时候就会报错,因为fs模块只有在node环境下有,这时候webpack就会去node_modules中找,可是fs是node的内置模块,所以webpack就会找不到。

module.noParse

js
noParse: /jquery/

不解析正则表达式匹配的模块,通常用它来忽略那些大型的单模块库,以提高构建性能

js
const path = require("path");

module.exports = {
  mode: "development",
  devtool: "source-map",

  module: {
    rules: [],
    noParse: /jquery/,
    /* 
      当我在a.js文件中使用了jquery,webpack在打包时就会进行分析模块依赖。
      但是jquery是一个单文件,无依赖的库,如果再让webpack执行AST语法树分析,就太耗费性能了。
      所以,我们指定不对jquery这个库来进行分析,即在代码中导入了该模块,webpack也不会将该模块进行分析,而是直接将原代码结果写入打包文件。
      这样就可以提高我们的《打包性能》,而不是运行性能。
    */
  },
};

resolve

resolve的相关配置主要用于控制模块解析过程

resoleve.modules

js
modules: ["node_modules"]  //默认值

当解析模块时,如果遇到导入语句,require("test"),webpack会从下面的位置寻找依赖的模块

  1. 当前目录下的node_modules目录

  2. 上级目录下的node_modules目录

  3. ...

    js
    module.exports = {
      mode: "development",
      devtool: "source-map",
    
      resolve: {
        modules: ["abc"],
        /* 
        首先要明确一个规则,
        1.就是在webpack中,查找模块的时候,是由webpack来进行的,而不是node,只是webpack和node的查找规则是一致的。
        2.查找规则:webpack先从当前目录找node_modules然后去上一级,一直找到根目录。
    
        3.
        if(Math.random()>0.5){
          require("./a.js")
        }
    
        问:打包结果是:
        A.  index.js和a.js
        B.  index.js
        C.  可能有a.js
        答案是A,因为webpack只负责打包,而不负责运行!
        */
      },
    };

resoleve.extensions

js
extensions: [".js", ".json"]  //默认值

当解析模块时,遇到无具体后缀的导入语句,例如require("test"),会依次测试它的后缀名

  • test.js

  • test.json

    js
    module.exports = {
      mode: "development",
      devtool: "source-map",
    
      resolve: {
        extensions: [".js", ".json",".vue"]
      },
    };
    
    //index.js
    require("./a");
    //webpack会自动补全后缀名,依靠的是extensions配置项。
    //webpack会根据extensions找对应的文件
    
    查找规则:
    //1.先找是否有a.js,没有的话是否有a文件夹,然后去找a文件夹下的package.json的入口,默认入口是index.js

resoleve.alias

js
alias: {
  "@": path.resolve(__dirname, 'src'),
  "_": __dirname
}

有了alias(别名)后,导入语句中可以加入配置的键名,例如require("@/abc.js"),webpack会将其看作是require(src的绝对路径+"/abc.js")

在大型系统中,源码结构往往比较深和复杂,别名配置可以让我们更加方便的导入依赖

js
const path = require("path");

module.exports = {
  mode: "development",
  devtool: "source-map",

  resolve: {
    extensions: [".js", ".json"],
    alias: {
      "@": path.resolve(__dirname, "src"),//配置路径别名,绝对路径
    },
  },
};

//使用
import img from "@/assets/img.png"//@代表src目录

externals

表示指定的外部模块不要打包到bundle,而是以配置的规则导出。

该配置是让webpack打包的时候,不将配置的模块打包进buldle,这样可以减少bundle的体积。

js
externals: {
    jquery: "$",//将query不打包进bundle,而是在bundle中将$导出
    lodash: "_"
}
  • 示例

从最终的bundle中排除掉配置的配置的源码,例如,入口模块是

js
//index.js
require("jquery")
require("lodash")

生成的bundle是:

js
(function(){
    ...
})({
    "./src/index.js": function(module, exports, __webpack_require__){
        __webpack_require__("jquery")
        __webpack_require__("lodash")
    },
    "jquery": function(module, exports){
        //jquery的大量源码
    },
    "lodash": function(module, exports){
        //lodash的大量源码
    },
})

但有了上面的配置后,则变成了

js
(function(){
    ...
})({
    "./src/index.js": function(module, exports, __webpack_require__){
        __webpack_require__("jquery")
        __webpack_require__("lodash")
    },
    "jquery": function(module, exports){
        module.exports = $;//将jquery以$导出
    },
    "lodash": function(module, exports){
        module.exports = _;
    },
})

index.html

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <!--cdn引入了jquery $ -->
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
    <!--cdn引入了lodash _ -->
    <script src="https://cdn.bootcss.com/lodash.js/4.17.15/lodash.core.min.js"></script>
    <script src="./index.js"></script>
</body>
</html>
<!--
	我不想让jquery和lodash打包进dist的bundle,我使用cdn的方式将jquery和lodash引入了。
	这样我在项目中就直接可以使用$和_了,而webpack的配置项externals就是将jquery和lodash以$和_的形式导出了,而不打包进bundle
-->

这比较适用于一些第三方库来自于外部CDN的情况,这样一来,即可以在页面中使用CDN,又让bundle的体积变得更小,还不影响源码的编写

stats

stats控制的是构建过程中控制台的输出内容

js
var path = require("path")
module.exports = {
    mode: "development",
    devtool: "source-map",
    /*用来控制命令行的输出信息,详情请看官网配置*/
    stats: {
        colors: true,//输出信息带颜色
        modules: false,//是否输出打包的文件
        hash: false,//不显示hash
        builtAt: false//不显示构建时间
    }
}

MIT License