如何在使用Webpack进行编译时替换文件?

5ta*_*ter 4 javascript webpack webpack-loader webpack-4

我有一个具有多个配置的项目。第一个配置是config.dev.js包含一些开发配置的文件。我在开发模式下使用它。第二个配置是config.js文件。我在生产模式下使用它。

在我使用导入的代码中:

import * as config from './config.js';
Run Code Online (Sandbox Code Playgroud)

我想在开发中使用第一个配置文件,而在不重写所有导入的情况下在生产中使用第二个。如何根据构建模式替换此配置?

Zer*_*er0 12

这是一个老问题,但我最近偶然发现了同样的问题,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")
        }
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)


Jac*_*ャック 7

我意识到这是一篇过时的文章,但这是Google的首批结果之一,因此我认为更好的答案会很好。

Webpack有一个内置的“ 普通模块替换插件 ”。

plugins: [
  new webpack.NormalModuleReplacementPlugin(
    /some\/path\/config\.development\.js/,
    './config.production.js'
  )
]
Run Code Online (Sandbox Code Playgroud)

供我使用,我将env文件放在一个变量中,这是一个示例:

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
        ),
        ...
    ]
}
Run Code Online (Sandbox Code Playgroud)

  • 也许值得一提的是,第二条路径相对于第一条路径,意味着:如果我的旧路径位于`./src/config/dev.js`中,则`./prod.js`将引用`./src/ config/prod.js`,而不是`root/prod.js` (4认同)

小智 5

您可以使用webpack file-replace-loader

https://www.npmjs.com/package/file-replace-loader

例:

//webpack.config.js

const resolve = require('path').resolve;

module.exports = {
  //...
  module: {
    rules: [{
      test: /\.config\.js$/,
      loader: 'file-replace-loader',
      options: {
        condition: process.env.NODE_ENV === 'development',
        replacement: resolve('./config.dev.js'),
        async: true,
      }
    }]
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我想模仿 Angular fileReplacements 语法,因此我使用了像 Angular 一样的 config.json,如果配置密钥与我传递给 webpack 的 env 匹配,则循环替换并创建多个 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"
                }
            ]
        }
    }
}

Run Code Online (Sandbox Code Playgroud)
// 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
            ]
       }
    }
}

Run Code Online (Sandbox Code Playgroud)

这样你就不必继续搞乱 webpack 和 regex 测试,只需添加到 config.json 中的数组即可