問題
我使用的依賴:
"antd-theme-webpack-plugin": "^1.3.9"
在
vue.config.js
裡配置了
const path = require("path");
const AntDesignThemePlugin = require('antd-theme-webpack-plugin');
const options = {
antDir: path.join(__dirname, './node_modules/ant-design-vue'),
stylesDir: path.join(__dirname, './src'),
varFile: path.join(__dirname, './src/assets/styles/theme/variables.less'),
themeVariables: ['@primary-color'],
generateOnce: false
}
const themePlugin = new AntDesignThemePlugin(options);
module.exports = {
css: {
loaderOptions: {
less: {
modifyVars: {
'primary-color': '#1DA57A',
},
javascriptEnabled: true
},
}
},
configureWebpack: {
plugins: [ themePlugin ]
},
}
啟動服務就報錯了:錯誤如下
Error LessError: Cannot find module 'antd/lib/style/themes/default.less'
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CN4cTNzEDNwkDNjNjMzczMzYzX0ITNxIDMxAzLcBTMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
LessError: error evaluating function
darken
: color.toHSL is not a function
原因排查分析
既然報錯說找不到
antd/lib/style/themes/default.less
檔案,我們可以去全局搜尋哪裡使用了
antd/lib/style/themes/default.less
。
我們可以看到在
ant-design-vue-pro\node_modules\antd-theme-webpack-plugin\node_modules\antd-theme-generator\index.js
檔案的 362 行使用了。是以問題就定位到了這個檔案,而這個檔案所在的包是
antd-theme-generator
,
antd-theme-webpack-plugin
裡面使用了
antd-theme-generator
。
我們找到https://github.com/mzohaibqc/antd-theme-webpack-plugin/blob/master/package.json,可以看到依賴的是
1.2.8
我們檢視其他版本的,比如:
1.2.3
,發現代碼
fileContent = @import "~antd/lib/style/themes/default.less";\n${fileContent};
注釋掉了,是以斷定是這個依賴的版本有問題。
解決
其實上面的版本
"antd-theme-generator": "^1.2.3"
,要測試出來符合
antd-theme-webpack-plugin: 1.3.9
,需要我們獨自分離這兩個包,因為我們安裝的是
antd-theme-webpack-plugin: 1.3.9
依賴,而
antd-theme-generator
的版本是由
antd-theme-webpack-plugin
控制的。
我的做法是自己複制一份
antd-theme-webpack-plugin
的代碼,當做我們的自定義插件,然後自己主動安裝
"antd-theme-generator": "^1.2.3"
即可。
我們建立一個
ant-design-vue-pro\webpack-plugins\antd-theme-webpack-plugin.js
插件:裡面的代碼直接複制
antd-theme-webpack-plugin
的代碼。
// https://github.com/mzohaibqc/antd-theme-webpack-plugin/blob/master/index.js
const { generateTheme } = require("antd-theme-generator");
const webpack = require("webpack");
const { RawSource } = webpack.sources || require("webpack-sources");
const path = require("path");
class AntDesignThemePlugin {
constructor(options) {
const defaultOptions = {
varFile: path.join(__dirname, "../../src/styles/variables.less"),
antDir: path.join(__dirname, "../../node_modules/antd"),
stylesDir: path.join(__dirname, "../../src/styles/antd"),
themeVariables: ["@primary-color"],
indexFileName: "index.html",
generateOnce: false,
lessUrl: "https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.2/less.min.js",
publicPath: "",
};
this.options = Object.assign(defaultOptions, options);
this.generated = false;
this.version = webpack.version;
}
apply(compiler) {
const pluginName = "AntDesignThemePlugin";
if (this.version.startsWith("5.")) {
compiler.hooks.thisCompilation.tap(pluginName, (compilation) => {
compilation.hooks.processAssets.tapAsync(
{
name: pluginName,
stage:
webpack.Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE,
},
(assets,) =>
this.addAssets(compilation, assets, callback)
);
});
} else {
compiler.hooks.emit.tapAsync(pluginName, (compilation,) =>
this.addAssets(compilation, compilation.assets, callback)
);
}
}
addAssets(compilation, assets,) {
this.generateIndexContent(assets, compilation);
if (this.options.generateOnce && this.colors) {
this.generateColorStylesheet(compilation, this.colors);
return callback();
}
generateTheme(this.options)
.then((css) => {
if (this.options.generateOnce) {
this.colors = css;
}
this.generateColorStylesheet(compilation, css);
callback();
})
.catch((err) => {
callback(err);
});
}
generateIndexContent(assets,) {
if (
this.options.indexFileName &&
this.options.indexFileName in assets
) {
const index = assets[this.options.indexFileName];
let content = index.source();
if (!content.match(/\/color\.less/g)) {
const less = `
<link rel="stylesheet/less" type="text/css" href="${this.options.publicPath}/color.less" />
<script>
window.less = {
async: false,
env: 'production'
};
</script>
<script type="text/javascript" src="${this.options.lessUrl}"></script>
`;
const updatedContent = content
.replace(less, "")
.replace(/<body>/gi, `<body>${less}`);
if (this.version.startsWith("5.")) {
compilation.updateAsset(
this.options.indexFileName,
new RawSource(updatedContent),
{ size: updatedContent.length }
);
return;
}
index.source = () => updatedContent;
index.size = () => updatedContent.length;
}
}
}
generateColorStylesheet(compilation,) {
if (this.version.startsWith("5.")) {
compilation.emitAsset("color.less", new RawSource(source), {
size: source.length,
});
return;
}
compilation.assets["color.less"] = {
source: () => source,
size: () => source.length,
};
}
}
module.exports = AntDesignThemePlugin;
然後安裝依賴,
webpack-sources
有就不需要安裝了。然後我從
1.2.0
開始往上找,找到了
1.2.3
版本不會報錯。
npm install
最後修改
vue.config.js
配置裡的引用自己定義的插件,其他不需要改動。
const AntDesignThemePlugin = require('./webpack-plugins/antd-theme-webpack-plugin');