如何配置vue应用程序(使用vue-cli)将nonce属性添加到生成的脚本标记中



我有一个使用vue-cli编译的vue应用程序。我的vue.config.js文件看起来像:

'use strict';
module.exports = {
publicPath: `${process.env.CDN_URL || ''}/dist/`,
lintOnSave: true,
transpileDependencies: [],
outputDir: '.tmp/dist',
pages: {
navigator: {
entry: 'vue/home/main.ts',
template: 'views/home/index.ejs',
// Will output to dist/views/home/index.ejs
filename: 'views/home/index.ejs',
},
},
chainWebpack(config) {
// Override the default loader for html-webpack-plugin so that it does not fallback to ejs-loader.
// ejs-loader will use ejs syntax against the template file to inject dynamic values before html-webpack-plugin runs
config.module
.rule('ejs')
.test(/.ejs$/)
.use('html')
.loader('html-loader');
},
};

我想让webpack为它生成的每个脚本标记添加nonce="<%= nonce %>"。我看到webpack有一个__webpack_nonce__变量,但我已经尝试在vue.config.js文件的许多部分中设置它。我已经尝试将它添加到chainWebpack((和configWebpack中。我已经尝试将它添加到vue/home/main.ts文件中。似乎什么都不管用。如何将nonce属性添加到脚本标记中?

这是vue 2.6.x和vue cli 4.5.x

我最终编写了自己的webpack插件,因为我的用例比ext-html webpack脚本插件所能支持的要复杂一些。我需要${nonce}作为标题标签,<%= nonce %>作为正文标签。我的插件代码是一个简单的基于脚本的ext-html webpack插件,由@shinx 提到

const HtmlWebpackPlugin = require('html-webpack-plugin');
class AddNonceToScriptTagsWebpackPlugin {
apply(compiler) {
compiler.hooks.compilation.tap(this.constructor.name, (compilation) => {
const alterAssetTagGroups = compilation.hooks.htmlWebpackPluginAlterAssetTags || HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups;
alterAssetTagGroups.tap(this.constructor.name, (data) => {
data.head = this._addNonceAttribute(data.head || []);
data.body = this._addNonceAttribute(data.body || []);
return data;
});
});
}
_addNonceAttribute(tags) {
return tags.map((tag) => {
if (tag.tagName === 'script') {
tag.attributes = tag.attributes || {};
tag.attributes.nonce = '<%= nonce %>';
} else if (tag.tagName === 'link' && tag.attributes && tag.attributes.as === 'script') {
tag.attributes = tag.attributes || {};
// eslint-disable-next-line no-template-curly-in-string
tag.attributes.nonce = '${nonce}';
}
return tag;
});
}
}

更新后的vue.config.js文件看起来像:

'use strict';
module.exports = {
publicPath: `${process.env.CDN_URL || ''}/dist/`,
lintOnSave: true,
transpileDependencies: [],
outputDir: '.tmp/dist',
pages: {
navigator: {
entry: 'vue/home/main.ts',
template: 'views/home/index.ejs',
// Will output to dist/views/home/index.ejs
filename: 'views/home/index.ejs',
},
},
configureWebpack: {
plugins: [
new AddNonceToScriptTagsWebpackPlugin(),
],
},
chainWebpack(config) {
// Override the default loader for html-webpack-plugin so that it does not fallback to ejs-loader.
// ejs-loader will use ejs syntax against the template file to inject dynamic values before html-webpack-plugin runs
config.module
.rule('ejs')
.test(/.ejs$/)
.use('html')
.loader('html-loader');
},
};

一个解决方案应该是将script ext html webpack插件添加到webpack.prod.conf文件(或您自己的webpack配置文件(的插件列表中。

new ScriptExtHtmlWebpackPlugin({
custom: {
test: /.js$/, // adjust this regex based on your demand
attribute: 'nonce',
value: '<%= nonce %>'
}
}),

最新更新