Vue + Webpack:将config.js从打包工作中排除,但不会加载

时间:2019-04-05 08:45:42

标签: vue.js webpack config

我想要的:

在我的Vue项目中,执行vue run build时,所有内容都打包(webpack)到dist目录中。

我可以将整个程序包部署到测试服务器,但是由于测试服务器需要另一组凭据(用于数据库等),因此每个环境中的一个文件config.js必须不同。

我的策略:

  • config.js打包到app.12314 ... js包中
  • config.js定义为未经更改而作为文件发出(通过webpack的file-loader

我做什么:

在需要配置数据的Vue组件文件中,通过以下方式包含配置:

<script>
  import config from '@/config/config.js';
</script>

我创建了一个vue.config.js文件,用于修改如下所示的默认Webpack设置:

const path = require("path");

// vue.config.js
module.exports = {
  publicPath: '/',
  configureWebpack: {
    module: {
      rules: [
        {
          test: /config.*config\.js$/,
          use: [
            {
              // exclude config file from being packed. The config file should simply reside as a plain file on the
              // file system, since it must be replaced with the target environoment specific config file on the server,
              // e.g. for setting the correct database connection
              loader: 'file-loader',
              options: {
                name: 'config/config.js'
              },
            }
          ]
        }
      ]
    }
  }
}

我的期望:

  • config.js将作为普通文件发出,不捆绑=> dist文件夹将包含捆绑的app....js文件和单独的config.js文件
  • 我可以将dist文件夹的内容部署到测试服务器,并且生成的代码将充分处理 loading config.js,以便组件可以使用配置数据

问题:

已授予config.js作为文件发出,因此我的dist文件夹如下所示:

.
├── config
│   └── config.js
├── css
│   ├── app.eb377513.css
│   └── chunk-vendors.2da46af1.css
├── favicon.png
├── index.html
└── js
    ├── app.724607ed.js
    ├── app.724607ed.js.map
    ├── chunk-vendors.426dad42.js
    └── chunk-vendors.426dad42.js.map

如您所见,一个单独的文件config.js!所有其他JS代码已捆绑到app.724607ed.js中。到目前为止,一切都很好。

但是,测试服务器上的应用程序将加载config.js,因此每个尝试使用其中的变量的组件都会失败。

我注意到,在Chrome的开发人员工具中,config.js没有网络流量。显然,webpack代码不会尝试从文件系统实际加载文件。我希望情况会自动如此。

  1. 我在做什么错,我想念什么?
  2. 这是从打包中排除配置文件的最佳实践吗?

1 个答案:

答案 0 :(得分:1)

显然,Webpack的file-loader确实单独发出了文件(好),但是没有添加代码将其加载到webapp中(不好)。我假设file-loader将负责在<script>文件中插入正确的index.html标签,以便:

  • 单独发出的config.js文件将被加载
  • 在开发方,使用config.js的语法与其他(打包的)工件相同,如下所示:

(在Vue组件文件中:)

<script>
    import backend from '@/utils/backend.js'; // <-- normal way of requiring modules in Vue component
    import config from '@/config/config.js'; // <-- would work the same, but actually will load emitted file
</script>

不幸的是,看来我错了。由于Webpack不在乎将文件加载到webapp中,因此我切换为手动方式,如下所示:

第1步:作为单独的文件发射

这一点很重要,因为我希望将config.js文件分开(不要与Vue应用程序的其余部分一起打包和缩小)。我已经在问题中描述了如何执行此操作(为config.js定义一个单独的规则,并为其使用file-loader

第2步:请小心将配置文件加载到网络应用中

由于file-loader未添加加载代码,因此请手动进行设置。在index.html中,插入以下行:

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.png">
    <script type="text/javascript" src="config/config.js" ></script> <-------- insert this line!
    <title>replayer-gui4</title>
</head>

第3步:更改config.js以与旧版导入方法兼容(不带ES2015模块)

现在,commonJS语法不再可行,因为config.js应该由浏览器加载。而且我不确定如何将ES2015类型模块加载(使用本机import语法)与Webpack代码混合(将所有import替换为Webpack加载代码)。因此,我决定切换到旧方法:让config.js像以前一样简单地注册一个全局变量(“ yuck!”):

var config = (() => {
    return {
        databaseCredentials: ...
    };
})();

因此,在每个使用配置设置的Vue模块中,调整“导入”代码-只需删除导入即可,因为无论如何变量config都将在全局范围内可用(在我们在此步骤对config.js进行更改之后) ):

<script>
    // import config from '@/config/config.js'; // <-- commented out - or just REMOVE this line
</script>

第4步:触发Webpack完全考虑使用config.js

现在唯一的警告是,由于config.js语句中的Java文件中从未引用过import,因此Webpack不会“查找”该文件,也不会考虑它。这意味着config.js也永远不会发出。

因此,请在App.vue中强制Webpack处理它:

<script>
    import configDummy from '@/config/config.js';
</script>

请注意,我们从不使用configDummy引用(变量),这只是Webpack找到它-并将其规则应用于文件。在这种情况下,规则是:将其作为单独的文件发布到dist文件夹中(即生成一个dist/config/config.js文件)

就是这样!我们使用了Webpack的file-loader,因此config.js不会被缩小并捆绑到应用程序捆绑包中,而是作为一个单独的文件保存。此外,我们还负责通过index.html加载它,这意味着配置设置是全局可用的。

我对此解决方案不满意的是,对于此特殊文件,使用import方法的好的方法已经损坏。但是我发现没有简单的解决方案可以使Webpack处理这些事情。

如果有人有建议,我会很高兴听到!

更新09.04.2019 :不,这不是理想的解决方案。这适用于打包/部署(npm run build部分),但不适用于开发服务器(npm run serve部分)。为了使开发服务器正常工作,我不得不将config.js复制到路径public/config/config.js中,以便开发服务器可以在index.html告诉它的位置找到它,即{ {1}}(相对于config/config.js文件已解决)。

因此,再次:它可以工作,但是有点笨拙。而且我不喜欢这种解决方案。