-
Notifications
You must be signed in to change notification settings - Fork 11.9k
Description
Requirement
I have three app in project. They use shared code. AppA uses part A from shared code, AppB uses part B and third AppC uses both A and B parts. So I need something like conditional compilation to reduce bundle size for AppA and AppB.
Another requirement is to pass some parameters like connection address or build number to code.
Third one feature which could be nice to have is ability to define environment variable on computer and use it when build\serve. So on dev machine you can get only dev build - "safety barrier".
Possible solution
Webpack has DefinePlugin and it can help to implement all three features. We should just change CLI config schema
"defines": {
"type": "array",
"description": "defines",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the def"
},
"value": {
"oneOf": [{"type": "string"}, {"type": "number"}, {"type": "boolean"}],
"description": "Value of the def for all targets"
},
"targets": {
"type": "object",
"properties": {
"development": {
"oneOf": [{"type": "string"}, {"type": "number"}, {"type": "boolean"}],
"description": "Value of the def for development target"
},
"production": {
"oneOf": [{"type": "string"}, {"type": "number"}, {"type": "boolean"}],
"description": "Value of the def for production target"
}
}
}
}
},
"default": []
}
and add plugin in common webpack config
new webpack.DefinePlugin(
appConfig.defines.reduce(
(defines, item) => {
if (item && item.name){
let name = item.name;
let value = item.targets ? item.targets[buildOptions.target] : item.value;
if (typeof value === 'string') {
value = JSON.stringify(eval(value));
}
defines[name] = value;
}
return defines;
}, {}
)
)
How to use:
- config your app
"defines": [
{
"name": "DEFINE_OPTION",
"value": true
},
{
"name": "ENV_OPTION",
"value": "process.env.ENV_OPTION"
},
{
"name": "COMMAND_LINE_OPTION",
"value": "buildOptions.command_line_option"
},
{
"name": "CALC_OPTION",
"value": "2 + 2"
}
]
- Run
ENV_OPTION="my value"
ng serve --command_line_option=42
somewhere in your code
declare var DEFINE_OPTION: boolean;
declare var ENV_OPTION: string;
declare var COMMAND_LINE_OPTION: string;
declare var CALC_OPTION: number;
if (DEFINE_OPTION){
//this code will be excluded by optimizer if !DEFINE_OPTION
}
As bonus (?) you can define some logic (see CALC_OPTION). Another thing - access to buildOptions. It allows to get command line args fast and easy, but looks a bit dirty