我有一个具有多个配置的项目。第一个配置是config.dev.js
文件,其中包含一些开发配置。我在开发模式下使用它。第二个配置是config.js
文件。我在生产模式下使用它。
在我使用导入的代码中:
import * as config from './config.js';
我想在开发中使用第一个配置文件,而在不重写所有导入的情况下使用生产中的第二个配置文件。如何根据构建模式替换此配置?
答案 0 :(得分:4)
这是一个古老的问题,但是我最近偶然发现了同一问题,并且webpack.NormalModuleReplacementPlugin
似乎不再起作用(或者至少在我而言,我使用JSON文件作为配置)。相反,我找到了另一个使用别名的解决方案:
const path = require("path");
modules.export = {
...
resolve: {
...
alias: {
[path.resolve(__dirname, "src/conf/config.json")]:
path.resolve(__dirname, "src/conf/config.prod.json")
}
}
...
}
答案 1 :(得分:3)
我意识到这是一篇过时的文章,但这是Google的第一批结果之一,所以我认为更好的答案会很好。
Webpack具有内置的“ Normal Module Replacement Plugin”。
plugins: [
new webpack.NormalModuleReplacementPlugin(
/some\/path\/config\.development\.js/,
'./config.production.js'
)
]
我将环境文件放在一个变量中,这是一个示例:
let envFilePath = './environment.dev.js';
if (env === 'production') {
envFilePath = './environment.prod.js';
} else if (env === 'staging') {
envFilePath = './environment.stg.js';
}
module.exports = {
// other webpack stuff
....
plugins:[
new webpack.NormalModuleReplacementPlugin(
/src\/environment\/environment\.js/,
envFilePath
),
...
]
}
答案 2 :(得分:2)
答案 3 :(得分:1)
您还可以像这样使用 babel-loader :
//webpack.config.js
const resolve = require('path').resolve;
module.exports = {
//...
module: {
strictExportPresence: true,
rules: [{
test: /\.config\.js$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
plugins: [
[
"module-resolver",
{
resolvePath(sourcePath, currentFile, opts) {
if(process.env.NODE_ENV === 'development') {
return sourcePath.substr(0, sourcePath.lastIndexOf('/')) + '/config.dev.js';
} else {
return sourcePath;
}
}
}
]
]
}
}]
}
}
通过这种方式,您甚至可以定义复杂的算法来确定要使用的文件。
答案 4 :(得分:1)
我想模仿Angular fileReplacements语法,所以我像Angular一样使用了config.json,如果配置密钥与env匹配,我将传递给webpack,循环进行替换,并创建一些Webpack模块规则。
这不是有史以来最优雅的东西,但这就是我最终得到的:
// config.json
{
"title": "Some Title",
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
]
},
"lan": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.lan.ts"
}
]
}
}
}
// webpack.config.js
const appConfig = require('./config.json');
module.exports = (env, argv) => {
// env.build is like `ng build --prod` as `webpack --env.build=production`
const configuration = appConfig.configurations[env.build];
const fileReplacements = [];
// Safety Check
if(configuration && configuration.fileReplacements) {
// Iterate through replacements
for(const replacement of configuration.fileReplacements) {
// create Webpack module rule
const replace = {
test: path.resolve(replacement.replace),
loader: 'file-replace-loader',
options: {
replacement: path.resolve(replacement.with),
async: true
}
}
fileReplacements.push(replace);
}
}
return {
mode: //...
entry: //...
module: {
rules: [
{
//...
},
// Unpack anywhere here
...fileReplacements
]
}
}
}
通过这种方式,您不必一直困扰webpack和regex测试,只需将其添加到config.json中的数组中即可。
答案 5 :(得分:0)
另一种方法是使用Webpack.DefinePlugin。如果您有一个小的代码块想要有条件地包含进来,则特别有用。
示例如下:
// webpack.conf.js
// Code block that should be inserted or left blank
const ServiceWorkerReg = `window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js').then(registration => {
console.log('SW registered: ', registration);
}).catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});`
appConfig = {
plugins: [
new webpack.DefinePlugin({
__SERVICE_WORKER_REG: isDev ? '' : ServiceWorkerReg,
}),
]
...
}
// Some module index.js
__SERVICE_WORKER_REG
... // other non conditional code