Webpack tips

11.18

public path

https://webpack.js.org/guides/public-path

动态修改

public-path.js

__webpack_public_path__ = process.env.ASSET_PATH

入门文件 index.js

import './public-path'

使用 require.context 动态加载模块

require.context可以列出特定目录下匹配的文件,并返回一个加载对象。使用该对象加载对应文件即可。

+ template/
    |- table.jade
    |- table-row.jade
    |+ directory/
        |-folder.jade
const req = require.context("./templates", true, /^\.\/.*\.jade$/);

const tableTemplate = req("./table.jade");
// tableTemplate === require("./templates/table.jade");

const tableTemplateId = req.resolve("./table.jade");
// tableTemplateId === require.resolve("./templates/table.jade");

req.keys();
// is ["./table.jade", "./table-row.jade", "./directory/folder.jade"]

req.id;
// is i. e. 42

Loader, Plugin

  • Loader 用来对特定的资源文件进行内容转换。

      `webpack.config.js`
    
      ```javascript
      module: {
          rules: [
              {
                  test: /\.css$/,
                  use: [
                      {
                          loader: path.resolve('./src/utils/style-loader'),
                          options: {}
                      }
                  ]
              }
          ]
      }
      ```
    
      `./src/utils/style-loader`
    
      ```javascript
      const { px2rem } = require('css-convert');
    
      module.exports = function (source) {
          return px2rem(source, { rem: 16, dpr: 2 });
      }
      ```
    
  • Plugin 可以让开发者使用 webpack 全部的功能。相对 loader 更复杂也更强大。

CSS Module 通过 scope 保留全局样式

通常情况下,开启 CSS Module 后,导入的样式类名会附加随机后缀,实现本地化。有些情况下,需要保持类名不变,以修改全局的样式。

这时可以使用 scope:global选择器

:global .btn {
        color: green;
}

LESS import 使用 webpack alias

需要在最前面添加波浪号~

@import '~@/utils/base.less';

导出子模块

有时候需要在index.js中集中导出子模块,如果先importexport,会报错unexpected token。需要直接export from

export Card from './Card';

// or
export { default as Card } from './Card';

Webpack 加速

Webpack 2s 完成构建

动态加载目录中的所有文件

参考

在 ES6 中,import 和 export 都是静态加载。而 webpack 的 require.context 可以实现构建过程中的动态加载:

fucntion importAll(r) {
    return r.keys().map(r);
}

const images = importAll(require.context('./', false, /\.(png|jpe?g|svg)$/));

DefinePlugin 创建全局常量

说明

在编译时在前端代码中创建全局常量。适用于在开发和生产模式下实现不同行为,如日志打印、设置不同 URL、启用不同特性等。

new webpack.DefinePlugin({
        // Definitions
})

定义是一些键值对,遵循规则:

  • 值是字符串,作为代码片段直接使用
  • 值是非字符串,先字符串化
  • 值是对象,内部的键按相同的方式定义
  • 键前缀typeof,仅当调用typeof时定义生效

举例

webpack 配置

new webpack.DefinePlugin({
    PRODUCTION: JSON.stringify(true),
    VERSION: JSON.stringify('5fa3b9'),
    BROWSER_SUPPORTS_HTML5: true,
    TWO: '1+1',
    'typeof window': JSON.stringify('object'),
    'process.env': {
        NODE_ENV: JSON.stringify(process.env.NODE_ENV)
    }
});

前端代码使用

console.log('Running App version ' + VERSION);
if(!BROWSER_SUPPORTS_HTML5) require('html5shiv');
📖