1. 程式人生 > >ant-design-pro 使用總結—自定義打包 構建配置

ant-design-pro 使用總結—自定義打包 構建配置

ant-design-pro使用了umi.js,沒有直接使用webpack,我們要配置自定義的構建打包跟直接的webpack配置不太一樣。
首先,大部分的webpack打包配置都可以直接修改config/config.js來實現,比如 proxy,publicPath等。參考umi.js配置文件。https://umijs.org/zh/config/#基本配置。

這裡記錄一些針對性的配置。

hash配置。如何配置 umi.js,umi.css不使用hash檔名,其他非同步載入的檔案使用hash檔名?

我們的編譯生成的index.html檔案交給了後端,index.html上引用的umi.js,umi.css的版本號給後端控制,其他靜態資原始檔如js,css,圖片則放到cdn伺服器上,所以其他檔案則通過hash檔名來控制版本號。umi預設配置hash要麼是true要麼是false,不能滿足我們的需求。
怎麼辦?觀察發現打包構建生成的檔名是4.64e1afbe.chunk.css,4.6cf0f5d2.async.js這種格式,在node_modules中搜索.async.js,發現相關配置在node_modules/af-webpack下,程式碼如下:

 if (opts.hash) {
    webpackConfig.output.filename(`[name].[chunkhash:8].js`).chunkFilename(`[name].[chunkhash:8].async.js`);
  }
  const hash = !isDev && opts.hash ? '.[contenthash:8]' : '';
  webpackConfig.plugin('extract-css').use(require('mini-css-extract-plugin'), [{
    filename: `[name]${hash}.css`,
    chunkFilename: `[name]${hash}.chunk.css`
  }]);

手動修改對應內容,發現配置生效。但是我們不能直接個性它,而是要用外部配置來覆蓋它。

config/config.js 中有一個屬性 chainWebpack,使用了webpack-chain,詳細配置在config/plugin.config.js。
webpack-chain 配置文件: https://github.com/neutrinojs/webpack-chain/tree/v4
於是我們在config/plugin.config.js中新增程式碼:

//css的修改
config.plugin('extract-css').use(require('mini-css-extract-plugin'), [
	{
		filename: `[name].css`,
		chunkFilename: `[name].[contenthash:8].chunk.css`,
	},
]);
//js的修改
config.output.filename('[name].js');

編譯,成功。

第三方元件src/lib資料夾的處理。禁用css modules編譯以及babel編譯處理。

實際開發中,不是所有的依賴都會放到 node_modules中,特別是一些我們自定義修改過的依賴,在 src/lib資料夾下放置這些特殊的依賴元件。元件放在這個資料夾下的表現並不跟放到node_modules中一樣,很多的原生構建打包配置都對node_modules作了排除處理,主要是css modules和babel編譯的時候,src/lib資料夾也需要做對應處理。

css modules

ant-design-pro預設開啟了css modules。
如果css modules作用範圍不排除src/lib資料夾,會導致引入元件的樣式錯亂。
檢視config/config.js發現cssLoaderOptions中有個getLocalIdent方法,用來生成css modules最終的class名。有下面幾行程式碼:

if (
      context.resourcePath.includes('node_modules') ||
      context.resourcePath.includes('ant.design.pro.less') ||
      context.resourcePath.includes('global.less')
  ) {
      return localName;
    }

可以看出,node_modules,ant.design.pro.less,global.less 這幾種檔案下 css modules 使用原始的css class名稱,相當於是把這些檔案排除在css modules作用範圍之外了。於是我們要排除src/lib資料夾,只需要在這個函式中加一行:

if (
    context.resourcePath.includes('node_modules') ||
    context.resourcePath.includes('ant.design.pro.less') ||
    context.resourcePath.includes('global.less')||
	context.resourcePath.includes('/src/lib/')
    ) {
           return localName;
      }

babel排除

引用src/lib下部分es5寫的元件的時候,發現執行報錯:

TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them

因為babel轉譯的時候貌似預設都轉成嚴格模式了。本來只需要exclude一下這些元件的,但是umi的配置裡並沒有找到相關的項。同樣,我們在node_modules/af-webpack下搜尋babel相關配置。搜到如下程式碼:

webpackConfig.module
	.rule('js')
	.test(/\.js$/)
	.include.add(opts.cwd)
	.end()
	.exclude.add(/node_modules/)
	.end()
	.use('babel-loader')
	.loader(require.resolve('babel-loader'))
	.options(babelOpts); // module -> jsx

對應的,我們在config/plugin.config.js中新增下面的程式碼:

config.module
	.rule('js')
	.exclude.add(/\/src\/lib\/webuploader/)
	.end();

搞定。