Use webpack to use specific file based on node environment
Asked Answered
F

2

6

I'm working on a Vue app (using cli 3). A third party front end component requires a config file. I would like to use different files depending on my node env but am unclear how to do this. For example, my directory structure might have tree.production.js and tree.development.js. In my main javascript, I can't seem to specify

import {tree} from `./assets/tree.${process.env.NODE_ENV}.js`;

I also can't use .env files to specify

import {tree} from `./assets/tree.${process.env.VUE_APP_TREE}.js`;

What I'd like to try is utilize webpack a la the vue.config.js to use the correct file and rename it to tree.js so in my code I can just specify

import {tree} from "./assets/tree.js"

Or really any best practices on how to achieve this pretty mundane and seemingly routine dev/prod switch.

Something like

//vue.config.js
module.exports = {
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      // do something with tree.production.js...
    } else {
      // do something with tree.development.js
    }
  }
}
Frontage answered 28/1, 2019 at 20:2 Comment(0)
P
14

The root of your problem is that ES6 import (and export) are statically analyzed - meaning, you can't have dynamic values like you are trying. You can try dynamic imports using the import().then(module => ...) syntax, but that's not really what you need here.

I think you are looking for resolve.alias. It would look something like this in your webpack config:

  //...
  resolve: {
    alias: {
      'assets/tree': path.resolve(__dirname, `path/to/assets/tree.${process.env.NODE_ENV}.js`)
    }
  }

and inside your app you would import it like this:

import { tree } from 'assets/tree';
Palingenesis answered 28/1, 2019 at 20:53 Comment(3)
I see that const something = require(`./${dynamic}/file`).default works but cannot use require(`./${process.env.SOME_ENV}/file`) because process is not defined on the client.Octane
@Octane - sorry, just seeing this comment somehow, but most webpack setups (ex. create-react-app) should resolve environment variables for you (I think because of this plugin). I just tested on a react project and const foo = require(process.env.NODE_ENV === 'production' ? './bar' : './foo') worked for me. But you are right, generally process is not available on the frontend.Palingenesis
null-loader is super cool.Leannleanna
T
0

sorry to hear you are having trouble with this. You are right, you aren't going to be able to use the a static import solution to load your file. There are options out there though depending on what you plan to do with tree.js. I don't know what tree is, but I am assuming you are only concerned with running your code in a webpack environment.

So what options do you have, maybe consider one of these options:

Dynamic imports

This feels to me the most likely thing you want, if you are able to use an async approach with your code, you can dynamically load your code (also take advantage of code-splitting):

Conditionally load via proxy

In this answer, Alejandro Silva has used a proxy file to conditionally load the file based on an ENV_VAR. You can configure webpack not to require impossible paths.


Others that might fit your requirements

  • convict - For loading and merging configuration
Terminus answered 28/1, 2019 at 20:35 Comment(1)
the dynamic imports worked well Thanks! And I'm glad to finally have a working example of how to lazy load components. But because this particular component is the first one on app load, it is a little simpler to use resolve.alias based on Ryan's answer. Much less code.Frontage

© 2022 - 2024 — McMap. All rights reserved.