问题
I'm working with a standalone Angular console generated by JHipster and served by a Spring Boot server. I am looking to serve up the app with different properties based on the environment (local, dev, prod, etc).
I see a lot of posts about configuring the webpack build per-environment, but I need to specify URLs and other data into my Angular 2 4.x app directly- data that changes whether I am running the app in dev or in production. Is this type of per-environment configuration possible when we start Angular via webpack?
回答1:
I recommend the dotenv-webpack plugin.
webpack.config.js
const Dotenv = require('dotenv-webpack');
...
plugins: [
new Dotenv({
path: './.env'
})
]
.env
URL=http://example.com
ENV=PROD
...
This allows you to use process.env
to access the environment variables:
constructor(private http:HttpClient) {
http.get(`${process.env.URL}`).subscribe(t=> {
...
});
}
The environment variables are subsituted at build time.
回答2:
I did not end up installing the DotEnv plugin, but rather I implemented the DefinePlugin solution listed on the webpack page. Because I am a noob- I found the documentation confusing and the listed example did not work as it did not make use of the 'process.env' variable (which was a new concept to me).
Here's a rough step-by-step guide I used to setting up this system:
- Create a webpack.envName.js file for each environment you want to support.
- In addition to any build setup, create the
DefinePlugin
entry in each file that will utilize the custom property. In my initial tests, creating a "global" constant in my webpack.common would override the other environments so I avoided setting up the parameter there. - Create the DefinePlugin constant underneath the "process.env" key. This is a special key that js based systems use to store data for the particular process.
- modify your yarn, node, mvn, etc build to utilize your local dev environment if that's not already happening. In my situation our dev environment is in the cloud, so I created a default
local
environment for localized testing.- The defined constants are now accessible in their respective environments without any needed import type statements.
Here's an example snippet. My webpack.local.js file under the plugins
entry:
...
new webpack.DefinePlugin({
'process.env': {
NAME: JSON.stringify('local'),
API_URL: JSON.stringify('http://localhost:8000/'),
}
})
...
Let's say I want to access these values in my fakeService
typescript class:
~/src/main/webapp/fake-service.ts
@Injectable
export class FakeService {
private URL_ROOT = process.env.API_URL + 'api/v2/externalService/resource/';
constructor(private http: HTTP) {}
get(): Observable<any> {
if(process.env.NAME == 'local') {
console.log("Calling url at " + this.URL_ROOT);
}
return this.http.get(this.URL_ROOT).map((res: Response) => res.json());
}
}
There is probably a better way to do this (or will be in the future). Rather than building this process.env dependency into your application, it would probably be wise to create a Configuration
Service that loads these values and can be injected into services or components that need to utilize this data.
来源:https://stackoverflow.com/questions/47898424/environment-based-properties-for-angular-2-app-served-by-webpack