Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

自定义工程配置收集 #3179

Closed
chenbin92 opened this issue May 8, 2020 · 9 comments
Closed

自定义工程配置收集 #3179

chenbin92 opened this issue May 8, 2020 · 9 comments

Comments

@chenbin92
Copy link
Collaborator

chenbin92 commented May 8, 2020

关联 issue:ice-lab/icejs#197
针对需要修改 webpack 配置的场景整理一些常见 case

icejs 通过插件 build-plugin-react-app 提供核心的工程构建配置,如果需要修改这些配置,可以参考 文档

首先新建 build.plugin.js 文件作为一个自定义插件,然后写入以下代码:

module.exports = ({ context, onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
     // 常见需求怎么写参见 issue 回复
  });
}

最后在 build.json 里引入自定义插件即可:

{
  "plugins": [
    "./build.plugin.js"
  ]
}
@chenbin92
Copy link
Collaborator Author

修改 CSS Modules 规则

默认情况命名为 *.module.scss 的文件才会使用 CSS Modules,如果希望默认所有 scss 文件都是使用 CSS Modules:

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    config
      .module.rule('scss-module').test(/\.scss$/)
      .exclude.add(/node_modules/);
    config
      .module.rule('scss')
      .include.add(/node_modules/);
  });
};

新增 webpack 插件

const CircularDependencyPlugin = require('circular-dependency-plugin');

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    config
      .plugin('CircularDependencyPlugin')
      .use(CircularDependencyPlugin, [{
         // 插件参数
      }]);
  });
};

@chenbin92
Copy link
Collaborator Author

  • friendly-errors-webpack-plugin:友好的 webpack 错误展示插件
  • size-plugin: 构建 size 大小对比和 gzipped 插件

@ClarkXia
Copy link
Collaborator

自定义 css 输出路径

大部分场景下通过配置项 outputAssetsPath 配置 css 输出路径

{
  "outputAssetsPath": {
    "js": "js-dist",
    "css": "css-dist"
  }
}

如果自定义需求需要修改到 css 输出的文件名,需要定制 MiniCssExtractPlugin 插件的输出

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    config.plugin('MiniCssExtractPlugin').tap((args) => [Object.assign(...args, {
      filename: '[name]/index.css',
    })]);
  });
}

@ClarkXia
Copy link
Collaborator

修改内置 loader 规则

svg 文件默认使用 url-loader 进行处理,如需修改,可以通过自定义的方式

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    config.module.rule('svg')
      .use('svg') // 覆盖原先 svg 规则
      .loader(require.resolve('@svgr/webpack'))
      .options({});
  });
};

@ClarkXia
Copy link
Collaborator

ClarkXia commented Jun 17, 2020

修改 postcss 规则

const autoprefixer = require('autoprefixer');

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    // 按需选择需要生效的规则
    [
      'scss',
      'scss-module',
      'css',
      'css-module',
      'less',
      'less-module',
    ].forEach(rule => {
      if (config.module.rules.get(rule)) {
        config.module
          .rule(rule)
          .use('postcss-loader')
          .tap(() => ({
            plugins: [
              // icejs 内置 autoprefixer 规则
              autoprefixer({
                overrideBrowserslist: [
                  'last 2 versions',
                  'Firefox ESR',
                  '> 1%',
                  'ie >= 9',
                  'iOS >= 8',
                  'Android >= 4',
                ],
              }),
              // 此处添加其他自定义规则
            ]
          }));
      }
    });
  });
};
``

@imsobear imsobear pinned this issue Jun 28, 2020
@chenbin92
Copy link
Collaborator Author

自定义 HTML 压缩配置

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    if (config.plugins.get('HtmlWebpackPlugin')) {
      config.plugin('HtmlWebpackPlugin').tap((args) => [{
        ...args[0],
        // https://github.com/jantimon/html-webpack-plugin#minification
        minify: {
          collapseWhitespace: true,
          removeComments: true,
          removeRedundantAttributes: true,
          removeScriptTypeAttributes: true,
          removeStyleLinkTypeAttributes: true,
          useShortDoctype: true
        }
      }]);
    }
  });
};

@imsobear
Copy link
Collaborator

imsobear commented Nov 5, 2020

修改 webpack 基础配置

// local-plugin.js
module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    // 修改 webpack devServer.hot
    config.devServer.hot('dist');
    // 修改 webpack output.path
    config.output.path('dist');
  });
};

新增 webpack loader

// local-plugin.js
module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    config.module
      .rule('new-rule')
      .test(/\.scss$/)
      .use('sass-loader')
        .loader('sass-loader');
  });
};

修改已有 webpack loader

通过 build-plugin-ice-app 内置 webpack loader 的命名,请参考本章节[附录]

// local-plugin.js
module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    config.module.rule('scss')
      .use('MiniCssExtractPlugin.loader')
      // 规格 scss 规则中 MiniCssExtractPlugin.loader 的配置
      .tap((options) => ({ ...options, publicPath: '../' }));
  });
};

新增 webpack 插件

const WebpackPluginImport = require('webpack-plugin-import');

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    config
      // 定义插件名称
      .plugin('WebpackPluginImport')
      // 第一项为具体插件,第二项为插件参数
      .use(WebpackPluginImport, [[
        {
          libraryName: /@ali\/ice-.*/,
          stylePath: 'style.js',
        },
      ]]);
  });
};

修改已有 webpack 插件

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    config.plugin('HtmlWebpackPlugin').tap((args) => [
      // 修改默认 HtmlWebpackPlugin 的 template 属性
      { ...(args[0] || {}), template: require.resolve('./template/index.html') },
    ]);
  });
};

修改指定命令的 webpack 配置

module.exports = ({ onGetWebpackConfig, context }) => {
  const { command } = context;
  onGetWebpackConfig((config) => {
     // 执行 build-scripts start 命令时
    if (command === 'start') {
      config.devServer.historyApiFallback(true);
    }
    // 执行 build-scripts build 命令时
    if (command === 'build') {
      config.optimization.minimize(true);
    }
  });
};

@imsobear
Copy link
Collaborator

imsobear commented Nov 5, 2020

内置 webpack loader

rule 名称 对应 loader 名称 说明
css MiniCssExtractPlugin.loader、css-loader、postcss-loader 基础 css 规则
css-module MiniCssExtractPlugin.loader、css-loader、postcss-loader css module 规则
scss sass-loader、MiniCssExtractPlugin.loader、css-loader、postcss-loader scss 规则
scss-module sass-loader、MiniCssExtractPlugin.loader、css-loader、postcss-loader 基于 scss 的 css module 规则
less less-loader、MiniCssExtractPlugin.loader、css-loader、postcss-loader less 规则
less-loader less-loader、MiniCssExtractPlugin.loader、css-loader、postcss-loader 基于 less 的 css module 规则
woff2 woff2 woff2 文件加载规则
ttf ttf ttf 文件加载规则
eot eot eot 文件加载规则
svg svg svg 文件加载规则
img img 图片文件加载规则
jsx babel-loader js/jsx 文件加载规则
tsx babel-loader、ts-loader ts/tsx 文件加载规则

内置 webpack plugin

plugin 名称 对应 plugin 包名 用途说明
MiniCssExtractPlugin mini-css-extract-plugin 生成样式文件
FilterWarningsPlugin webpack-filter-warnings-plugin 优化构建输出
SimpleProgressPlugin webpack-simple-progress-plugin 显示加载进度条
CaseSensitivePathsPlugin case-sensitive-paths-webpack-plugin 解决加载包大小写敏感
DefinePlugin webpack.DefinePlugin 变量注入
HtmlWebpackPlugin html-webpack-plugin html 文件模版
CopyWebpackPlugin copy-webpack-plugin 拷贝 pulic 目录下文件

@imsobear
Copy link
Collaborator

imsobear commented Nov 5, 2020

修改 babel-loader 配置

module.exports = ({ onGetWebpackConfig }) => {
  onGetWebpackConfig((config) => {
    // 内置 jsx 和 tsx 规则均会使用到 babel 配置
    ['jsx', 'tsx'].forEach((rule) => {
      config.module
        .rule(rule)
        .use('babel-loader')
        .tap((options) => {
          // 添加一条 babel plugin,同理可添加 presets
          options.plugins.push(require.resolve('babel-plugin-transform-jsx-list'));

          // 修改 babel preset 配置,同理可修改 plugins
          options.presets = options.presets.map((preset) => {
            if (Array.isArray(preset)) {
              const [modulePath, presetOptions] = preset;
              // 判断指定配置
              if (modulePath.indexOf('preset-env') > -1) {
                return [
                  modulePath,
                  // 自定义新的 options
                  { ...presetOptions, modules: false },
                ];
              }
            }
            return preset;
          });
          return options;
        });
    });
  });
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants