Vue.js exclude settings file from being bundled
Asked Answered
T

1

4

I am using the vue-webpack template and I have created a settings.json file to store environment variables that should be changed when installing the script.

My settings.json (just store the absolute path to the API server):

{
  "apiURL": "//localhost/app/server/API"
}

How can I keep the file from being minified/bundled in the production version such that I can change it and the updated file will be used next time the app is accessed (without having to build it again) ?

In my app I use this file via require:

const SETTINGS = require('../settings.json');

I understand that by requireing it webpack will bundle it as a module, but how can I include it in my app such that the settings file will still be a separated file in the production build that I can edit.

Is there a better format/way to store those settings (so that they can be edited in production without re-building) ?

Tetrasyllable answered 15/4, 2017 at 15:57 Comment(0)
B
3

You can define those settings in an object that can be referenced in the externals configuration in webpack.config.js.

The externals configuration option provides a way of excluding dependencies from the output bundles. Instead, the created bundle relies on that dependency to be present in the consumer's environment.

Example:

externals: {
  appSettings: "appSettings",
  "window.appSettings": "appSettings"
}

Where appSettings is a global variable containing the environment variables you want to manipulate.


Alternatively, if you do not like that method that exposes the settings in the global object, you can do the following:

Export a variable with the default settings, which will be included in webpack bundle.

export var appSettings = {
  currentSettings: "",
  settings: {},
  getString: function(strName) {
    var sett = this.currentSettings ?
      this.settings[this.currentSettings] :
      appDefaultStrings;
    if (!sett || !sett[strName]) sett = appDefaultStrings;
    return sett[strName];
  },
  getSettings: function() { //Gets all available settings
    var res = [];
    res.push("");
    for (var key in this.settings) {
      res.push(key);
    }
    res.sort();
    return res;
  }
};

export var appDefaultStrings = {
  apiURL: "//localhost/app/server/API"
    //...
}
appSettings.settings["default"] = appDefaultStrings;

You can then require or import this variable and use it like so:

import appSettings from "../path/to/appSettings";

appSettings.getString("apiURL"); //"//localhost/app/server/API"

Now that you have your default settings up and running, we will create another file containing the custom settings.

import appSettings from "../path/to/appSettings";

export var appProductionSettings = {
  apiUrl: "http://example.com"
    //...
}

appSettings.settings["production"] = appProductionSettings;

The last thing you need to do is handle which settings you want to use. I have not used vue.js yet, but hopefully this will lead you in the right direction:

import appSettings from "../path/to/appSettings";

export class MyApp {
  constructor() {
    this.settingsValue = "";
  }
  get settings() {
    return this.settingsValue;
  }
  set settings(value) {
    this.settingsValue = value;
    appSettings.currentSettings = value;
  }
}

Change the settings:

import "../path/to/productionSettings";

var app = new MyApp();

app.settings = "production";

With this method you can create and use as many settings files as you want.

Brightness answered 15/4, 2017 at 16:58 Comment(1)
What best suits your requirement is the best option. If you're defining a global variable it may be worth using object.defineProperties to take advantage of property descriptors, especially writable (which defaults to false) . This will prevent users from changing the value with an assign operator instead of changing it in the file like you are expecting. Here is a quick example to clarify this: jsfiddle.Brightness

© 2022 - 2024 — McMap. All rights reserved.