关于使用 Vue (vue-loader) + Webpack 和 Chromatism
示例:(在开发/源代码上)
let textColor = chromatism.contrastRatio('#ffea00').cssrgb // => rgb(0,0,0)
是否可以在构建版本上告诉 Webpack将转换为rgb(0,0,0)
?
因此构建版本应转换为:(对于性能)
let textColor = 'rgb(0,0,0)'
答案 0 :(得分:5)
正如之前的答案和评论已经提到过,没有现成的AOT编译器来处理这种情况(我的意思是这是一个非常具体的案例,没有通用工具能够处理它),有没有什么能阻止你推出自己的装载机/插件来处理这个任务!
您可以使用自定义Webpack Loader和Node's VM Module在构建时执行代码,获取其输出并将其替换为源文件中的函数调用。
此想法的示例实现可能类似于以下代码段:
// file: chromatismOptimizer.js
// node's vm module https://nodejs.org/api/vm.html
const vm = require('vm')
const chromatism = require('chromatism')
// a basic and largley incomplete regex to extract lines where chromatism is called
let regex = /^(.*)(chromatism\S*)(.*)$/
// create a Sandbox
//https://nodejs.org/api/vm.html#vm_what_does_it_mean_to_contextify_an_object
// this is roughly equivalent to the global the context the script will execute in
let sandbox = {
chromatism: chromatism
}
// now create an execution context for the script
let context = new vm.createContext(sandbox)
// export a webpack sync loader function
module.exports = function chromatismOptimizer(source){
let compiled = source.split('\n').reduce((agg, line) => {
let parsed = line.replace(regex, (ig, x, source, z) => {
// parse and execute the script inside the context
// return value is the result of execution
// https://nodejs.org/api/vm.html#vm_script_runincontext_contextifiedsandbox_options
let res = (new (vm.Script)(source)).runInContext(context)
return `${x}'${res}'${z? z : ''}`
})
agg.push(parsed)
return agg;
}, []).join('\n');
return compiled;
}
然后在 production.webpack.js (或类似的某些文件)中取自this issue:
// Webpack config
resolveLoader: {
alias: {
'chromatism-optimizer': path.join(__dirname, './scripts/chromatism-optimizer'),
},
}
// In module.rules
{
test: /\.js$/,
use: ['chromatism-optimizer'],
}
注意:这只是一个参考实现,并且很大程度上是不完整的。这里使用的正则表达式是非常基本的,可能不包括许多其他用例,因此请确保更新正则表达式。此外,整个内容可以使用webpack插件实现(只是我没有足够的知识来创建一个)。如需快速入门refer to this wiki,了解如何创建自定义插件。
基本思路很简单。
首先创建一个沙盒环境,
let sandbox = { chromatism:chromatism, ...}
然后创建执行上下文,
let context = new vm.createContext(sandbox)
然后对于每个有效的源,在上下文中执行source语句并获得结果
let result = (new (vm.Source)(source)).runInContext(context)
然后可以用结果替换原始的源语句。
答案 1 :(得分:1)
尝试使用call-back加载程序处理所有JavaScript。为这个特定的案例定义一个回调函数,甚至是更通用的函数:
evalDuringCompile: function(code) { return JSON.stringify(eval(code)); }
答案 2 :(得分:0)
State of Art优化器无法处理任意表达式。在这种情况下,最可靠的解决方案是代码中的硬代码常量。
sample2
一些未来的优化器会处理这样的情况。 prepack将在编译时评估代码并输出计算值。但是,通常不认为生产准备就绪。