当前位置: 首页 > 文档资料 > San CLI 中文文档 >

高级配置

优质
小牛编辑
128浏览
2023-12-01

这篇文章介绍一些高级配置的配置项,这些配置项虽然在日常项目中配置的较少,但是对于项目来说这些配置项往往是可以解决日常常见的问题。

使用拆包

在项目中,不合理的 Bundle 是致命的。在 Webpack 中,总共提供了三种方式来实现代码拆分(Code Splitting):

  • entry 配置:通过多个 entry 文件来实现;
  • 动态加载(按需加载):通过写代码时主动使用import()或者require.ensure来动态加载;
  • 抽取公共代码:使用splitChunks配置来抽取公共代码。

在 San CLI 中可以通过splitChunks抽取公共代码。splitChunks的配置项跟 Webpack 中 optimizationsplitChunks是完全相同的。例如下面的配置:

module.exports = {
    // ...
    splitChunks: {
        cacheGroups: {
            vendors: {
                name: 'vendors',
                test: /[\\/]node_modules(?!\/@baidu)[\\/]/,
                // minChunks: 1,
                priority: -10
            },
            common: {
                name: 'common',
                test: /([\/]src\/components(-open)?|[\\/]node_modules\/@baidu\/nano)/,
                priority: -20,
                minChunks: 1,
                chunks: 'initial'
            }
        }
    }
};

同时 San CLI 内置了 optimize-css-assets-webpack-plugin,也就是说支持使用 splitChunks 来拆分 CSS 文件。

代码压缩和优化

在项目中可以对产出的代码中压缩和优化,在 San CLI 的 JS 使用了 terserjs 和 CSS 使用 cssnano。支持默认 San CLI 的配置是:

默认 cssnano 配置:

{
    mergeLonghand: false,
    cssDeclarationSorter: false,
    normalizeUrl: false,
    discardUnused: false,
    // 避免 cssnano 重新计算 z-index
    zindex: false,
    reduceIdents: false,
    safe: true,
    // cssnano 集成了autoprefixer的功能
    // 会使用到autoprefixer进行无关前缀的清理
    // 关闭autoprefixer功能
    // 使用postcss的autoprefixer功能
    autoprefixer: false,
    discardComments: {
        removeAll: true
    }
}

在 San CLI 的配置文件中,所有跟 CSS 的相关的配置是放在了css配置项中,所以对 cssnano 的修改也是在css.cssnanoOptions中进行修改:

module.exports = {
    // ...
    css: {
        cssnanoOptions: {
            // 自定义的配置
        }
    }
};

默认 terserjs 配置:

{
    comments: false,
    compress: {
        unused: true,
        // 删掉 debugger
        drop_debugger: true, // eslint-disable-line
        // 移除 console
        drop_console: true, // eslint-disable-line
        // 移除无用的代码
        dead_code: true // eslint-disable-line
    },
    ie8: false,
    safari10: true,
    warnings: false,
    toplevel: true
}

San CLI 的配置文件中使用terserOptions可以对默认的配置进行修改:

module.exports = {
    // ...
    terserOptions: {
        // 自定义的配置
    }
};

html-minifier 配置

除此之外,San CLI 中使用的 html-webpack-plugin 的配置项中可以使用 html-minifier,在 San CLi 中默认的配置如下:

{
    removeComments: true,
    collapseWhitespace: false,
    removeAttributeQuotes: true,
    collapseBooleanAttributes: true,
    removeScriptTypeAttributes: false,
    minifyCSS: true,
    // more options:
    // https://github.com/kangax/html-minifier#options-quick-reference
}

使用者可以在pages中的html-minifier进行配置,具体配置可以参考这里

编译 NPM 包中的 ES6 语法

在项目中,我们推荐使用 ESM 语法的模块,ESM 语法的模块在使用的同时,可以使用统一 的 Webpack 配置,并且基于 Tree-shaking,打出的包体积更加合理。但是在 San CLI 中,默认是不会编译 NPM 包中的 ES6 语法的代码,这时候依赖的 NPM 包中使用 ES6 语法,需要使用transpileDependencies

transpileDependencies可接受的类型为ArrayString或者RegExp。例如我们项目依赖@baidu/nano这个 UI 基础库,则可以设置配置如下:

module.exports = {
    // ...
    transpileDependencies: ['@baidu/nano']
};

这样nano这个模块就会被 Webpack 编译了。

使用 chainWebpack 和 configWebpack 进行个性化配置

如果要更加自主的进行个性化的配置,那么可以在 San CLI 配置文件中的 chainWebpack 和 configWebpack 进行修改,chainWebpack 接受的参数是 webpack-chain 语法的配置,configWebpack接受的参数是 Webpack 的配置对象。

例如:

// 静态文件域名
const CDN = 'https://s.bdstatic.com/';
// 生产环境下的静态目录
const STATIC_PRO = 'static/pro';

module.exports = {
    chainWebpack: config => {
        // 这里可以用来扩展 webpack 的配置,使用的是 webpack-chain 语法
        config.module
            .rule('img')
            .test(/\.(png|jpe?g|gif)(\?.*)?$/)
            .use('url-loader')
            .loader(require.resolve('url-loader'))
            .options({
                limit: 1000,
                name: STATIC_PRO + '/img/[name].[hash:7].[ext]',
                publicPath: __isProduction ? CDN : ''
            });

        config.module
            .rule('svg')
            .use('svg-url-loader')
            .loader(require.resolve('svg-url-loader'))
            .options({
                limit: 2500,
                name: STATIC_PRO + '/svg/[name].[hash:7].[ext]',
                publicPath: __isProduction ? CDN : ''
            });
    }
};

在配置文件中添加 Service 插件

plugins 增加自定义插件,例如:

module.exports = {
    plugins: [
        {
            id: 'built-in:plugin-progress',
            apply(api, projectOptions, options = {}) {
                api.chainWebpack(webpackConfig => {
                    options.color = require('san-cli-utils/randomColor').color;
                    webpackConfig.plugin('progress').use(require('webpackbar'), [options]);
                });
            }
        },
        'san-plugin.js'
    ]
};

添加 dev server 中间件

添加 dev server 中间件,需要使用 Service 的插件的addDevServerMiddleware方法,例如:

const plugins = [
    {
        id: 'middleware1',
        apply(api) {
            // 使用 api 配置dev server 中间件
            api.middleware(() =>
                require('hulk-mock-server')({
                    // 配置contentBase
                    contentBase: path.join(__dirname, './' + outputDir + '/'),
                    // 配置 mock 路径
                    rootDir: path.join(__dirname, './mock'),
                    // 配置解析器相关内容
                    processors: [
                        `smarty?router=/template/*&baseDir=${path.join(
                            __dirname,
                            `./${outputDir}/template`
                        )}&dataDir=${path.join(__dirname, './mock/_data_')}`
                    ] // eslint-disable-line
                })
            );
        }
    }
];
module.exports = {
    plugins
};

注意: 这里特殊说明下,middleware传入的是一个 function,并且返回一个中间件。

更多

如果想了解更多 Service 插件相关内容,那么请浏览这个文档