webpack学习

一、框架搭建

webpack-cli此工具用于在命令行中运行 webpack

npm install webpack webpack-cli --save-dev

创建webpack.config.js文件,这个是webpack的默认配置文件,会自动读取这个文件,当然也可以指定某个文件来读取,只需要在命令行中指定文件npx webpack --config xxx.js

//webpack.config.js
//最最基础的配置,导出一个空对象
module.exports = {
};
//或者
module.exports = (...args) =>{
	//导出一个函数来返回配置对象,推荐使用这个,因为函数可以接受一下传进来的参数,也能做更多的操作
	return {  
	}
}

二、entry入口

1. 单个入口
module.exports = {
  entry: './path/to/my/entry/file.js',  //简写
};

上面的写法是以下写法的简写

module.exports = {
  entry: {
    main: './path/to/my/entry/file.js',  //完整写法
  },
};

我们也可以定义多个主入口

module.exports = {
  entry: ['./src/file_1.js', './src/file_2.js'],
  output: {
    filename: 'bundle.js',
  },
};
2.对象语法入口
module.exports = {
  entry: {
    app: './src/app.js',   // app 和 adminApp就是chunk的名字,也可以通过runtime来自定义
    adminApp: './src/adminApp.js',
  },
};

用于描述入口的对象。你可以使用如下属性

  • ependOn: 当前入口所依赖的入口。它们必须在该入口被加载前被加载。
  • filename: 指定要输出的文件名称。
  • import: 启动时需加载的模块。
  • library: 指定 library 选项,为当前 entry 构建一个 library。
  • runtime: 运行时 chunk 的名字。如果设置了,就会创建一个新的运行时 chunk。在 webpack 5.43.0 之后可将其设为 false 以避免一个新的运行时 chunk。
  • publicPath: 当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址

三、出口(output)

即使可以存在多个entry起点,但只能指定一个output配置

//单个入口时,可以使用下面的方法
module.exports = {
  output: {
    filename: 'bundle.js',
  },
};

如果配置中创建出多于一个 “chunk”(例如,使用多个入口起点或使用像CommonsChunkPlugin这样的插件),则应该使用 占位符(substitutions) 来确保每个文件具有唯一的名称

module.exports = {
  entry: {
    app: './src/app.js',
    search: './src/search.js',
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist',
  },
};
1. assetModuleFilename

给所有module.rules中type等于assets的资源统一设置一个路径

module.exports = {
  entry: "./src/index.js",
  output: {
    filename: "bundle.[fullhash:6].js",
    path: path.resolve(__dirname, "dist"),
    assetModuleFilename: "images/[name].[hash:8][ext]",
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: "asset/resource",
      }
    ],
  },
};
2. asyncChunks

创建按需加载的异步 chunk

module.exports = {
  //...
  output: {
    //...
    asyncChunks: true,
  },
};
3.chunkFilename
  • 这个选项用来定义动态导入或异步加载的额外代码块(chunk)的文件名称。
  • 当你的应用使用动态import() 语法或者Code Splitting技术时,Webpack 会生成额外的 chunks,并且这些 chunks 的文件名将由 chunkFilename定义。
  • 这些额外的chunks可以是按需加载的内容或者是被分割出去的共享库。
module.exports = {
  entry: {
    main:"./src/index.js",
    main2:"./src/index2.js"
  },
  output: {
    filename: "[name].[fullhash:6].js",  //这个选项控制上面entry输出的文件名
    chunkFilename: '[name].[fullhash:6].js',  //这里控制不了上面entry输出的的文件名,
  },
};
module.exports = {
  //...
  output: {
    chunkFilename: (pathData) => {
      return pathData.chunk.name === 'main' ? '[name].js' : '[name]/[name].js';
    },
  },
};
4. chunkFormat

chunk 的格式(formats 默认包含 ‘array-push’ (web/WebWorker)、‘commonjs’ (node.js)、‘module’ (ESM),还有其他情况可由插件添加)
定义在webpack运行时产生的额外的chunk时候的格式

四、loader

在应用程序中,有两种使用 loader 的方式

  • 配置方式(推荐):在 webpack.config.js 文件中指定 loader
  • 内联方式:在每个 import 语句中显式指定 loader
1. 配置方式:
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          {
            loader: 'css-loader',
            options: {
              modules: true,
            },
          },
          { loader: 'sass-loader' },
        ],
      },
    ],
  },
};
2. 内联方式

多个loader之间使用!分割

import Styles from 'style-loader!css-loader?modules!./styles.css';

通过为内联 import 语句添加前缀,可以覆盖配置中的所有普通loader,前置loader,后置loader
使用 ! 前缀,将禁用所有已配置的 normal loader(普通 loader)

import Styles from '!style-loader!css-loader?modules!./styles.css';

使用 !! 前缀,将禁用所有已配置的 loader(preLoader, loader, postLoader)

import Styles from '!!style-loader!css-loader?modules!./styles.css';

使用 -! 前缀,将禁用所有已配置的 preLoader 和 loader,但是不禁用 postLoaders

import Styles from '-!style-loader!css-loader?modules!./styles.css';
3. loader 特性
  • loader 支持链式调用。链中的每个 loader 会将转换应用在已处理过的资源上。一组链式的 loader 将按照相反的顺序执行。链中的第一个 loader 将其结果(也就是应用过转换后的资源)传递给下一个 loader,依此类推。最后,链中的最后一个 loader,返回 webpack 所期望的 JavaScript。
  • loader 可以是同步的,也可以是异步的。
  • loader 运行在 Node.js 中,并且能够执行任何操作
  • loader 可以通过options对象配置
  • 除了常见的通过package.json的 main 来将一个 npm 模块导出为 loader,还可以在module.rules中使用 loader 字段直接引用一个模块
  • 插件(plugin)可以为 loader 带来更多特性
  • loader 能够产生额外的任意文件
4.loader的执行顺序
  • Pitching 阶段: loader 上的pitch方法,按照后置(post)行内(inline)普通(normal)前置(pre)的顺序调用
  • Normal 阶段:loader上的 常规方法,按照前置(pre)普通(normal)行内(inline)后置(post) 的顺序调用。模块源码的转换, 发生在这个阶段

五、plugins插件

webpack 插件是一个具有apply方法的 JavaScript 对象。apply 方法会被 webpack compiler 调用,并且在 整个 编译生命周期都可以访问 compiler 对象

const pluginName = 'ConsoleLogOnBuildWebpackPlugin';

class ConsoleLogOnBuildWebpackPlugin {
  apply(compiler) {
    compiler.hooks.run.tap(pluginName, (compilation) => {
      console.log('webpack 构建正在启动!');
    });
  }
}

module.exports = ConsoleLogOnBuildWebpackPlugin;

六、mode

提供 mode 配置选项,告知 webpack 使用相应模式的内置优化

1. 用法

只需在配置对象中提供 mode 选项

module.exports = {
  mode: 'development',
};

或者从CLI参数中传递

webpack --mode=development
选项描述
development会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development. 为模块和 chunk 启用有效的名
production会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production。为模块和 chunk 启用确定性的混淆名称,FlagDependencyUsagePlugin,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin 和 TerserPlugin
none不使用任何默认优化选项

如果没有设置,webpack 会给 mode 的默认值设置为production
如果要根据 webpack.config.js 中的 mode 变量更改打包行为,则必须将配置导出为函数,而不是导出对象:

var config = {
  entry: './app.js',
  //...
};

module.exports = (env, argv) => {
  if (argv.mode === 'development') {
    config.devtool = 'source-map';
  }

  if (argv.mode === 'production') {
    //...
  }

  return config;
};

七、module

1. generator

可以使用module.generator在一个地方配置所有生成器的选项

module.exports = {
  module: {
    generator: {
      asset: {
        // asseet 模块的 generator 选项

        // 自定义 asset 模块的 publicPath,自 webpack 5.28.0 起可用
        publicPath: 'assets/',

        // 将静态资源输出到相对于 'output.path' 的指定文件夹中,webpack 5.67.0 后可用
        outputPath: 'cdn-assets/',
      },
      'asset/inline': {
        // asset/内联模块的 generator 选项
      },
      'asset/resource': {
        // asset/资源模块的 generator 选项

        // 自定义 asset/resource 模块的 publicPath,自 webpack 5.28.0 起可用
        publicPath: 'assets/',

        // 将静态资源输出到相对于 'output.path' 的指定文件夹中,webpack 5.67.0 后可用
        outputPath: 'cdn-assets/',
      },
      javascript: {
        // 该模块类型尚不支持 generator 选项
      },
      'javascript/auto': {
        // 同上
      },
      'javascript/dynamic': {
        // 同上
      },
      'javascript/esm': {
        // 同上
      },
      // 其他...
    },
  },
};
2. noParse

防止 webpack 解析那些任何与给定正则表达式相匹配的文件。忽略的文件中 不应该含有import,require,define的调用,或任何其他导入机制。忽略大型的 library 可以提高构建性能

module.exports = {
  //...
  module: {
    noParse: /jquery|lodash/,
  },
};
module.exports = {
  //...
  module: {
    noParse: (content) => /jquery|lodash/.test(content),
  },
};
3. enforce

可能的值有:"pre" | "post"
指定 loader 种类。没有值表示是普通 loader。
pre前置,post后缀

module: {
    rules: [
      {
        enforce: "pre",
        test: /\.css$/i,
        use: ["style-loader", "css-loader"],
      }
    ],
  },
4. exclude

排除所有符合条件的模块

module: {
    rules: [
      {
        enforce: "pre",
        test: /\.css$/i,
        exclude: /node_modules/,  //排除node_modules里面的css文件
        use: ["style-loader", "css-loader"],
      }
    ],
  },
5. include

引入符合以下任何条件的模块

module: {
    rules: [
      {
        enforce: "pre",
        test: /\.css$/i,
        include: /node_modules/,  //排除node_modules里面的css文件
        use: ["style-loader", "css-loader"],
      }
    ],
  },
6. oneOf

当有规则匹配了,就不继续进行匹配

  module: {
    rules: [
      {
        oneOf: [
          {
            enforce: "pre",
            test: /\.css$/i,
            exclude: /node_modules/,
            use: ["style-loader", "css-loader"],
          },
          {
            test: /\.s[ac]ss$/i,
            use: ["style-loader", "css-loader", "sass-loader"],
          },
          {
            test: /\.(png|svg|jpg|jpeg|gif)$/i,
            type: "asset/resource",
            parser: {
              dataUrlCondition: {
                maxSize: 10 * 1024,
              },
            },
          },
        ],
      },
    ],
  },
7. parser
  module: {
    rules: [
      {
        oneOf: [
          {
            test: /\.(png|svg|jpg|jpeg|gif)$/i,
            type: "asset",
            parser: {
              dataUrlCondition: {  //文件大小小于10kb会被转换为base64,前提是上面的type不能是asset/resource
                maxSize: 10 * 1024,
              },
              generator:{
              	//给匹配到的资源在代码中添加上这个公共路径  background-image: url("../assets/imgs/progress.png")变成了
              	//http://127.0.0.1:5500/dist/cdn-assets/tabbar_active.cae5338e.png;
              	publicPath:"cdn-assets/",  
              	outputPath:"cdn", //在filename上拼接这个路径,5.67.0+版本可用
              	filename: 'images/[name][ext]'  //自定义输出路径和文件名
              }
            },
          },
        ],
      },
    ],
  },

八、resolve

resolve:{
    alias:{
      "@": path.resolve(__dirname, "src")  //别名
    },
     //用于控制是否允许省略文件扩展名。当设置为 true 时,Webpack会强制要求在导入模块时必须显式指定文件扩展名;
     //当设置为 false 时,则允许省略文件扩展名
    enforceExtension:false,
    extensions: ['.js', ".mjs",'.json', '.ts'],  //省略扩展名时,用于匹配的后缀
    //上面那种写法会覆盖默认扩展名,意味着你必须把所有用到的扩展名补全,
    //如果只想添加某个扩展名,并且也使用默认扩展名,就使用下面的方式
    //extensions: ['.ts', '...'] 
  },

九、optimization

module.exports = {
  //...
  optimization: {
    splitChunks: {  //代码分割,以下都是默认值
      chunks: 'async',
      minSize: 20000,
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
        },
      },
    },
  },
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值