Skip to content

Commit c7e655c

Browse files
committed
feat(@angular/cli): add environment option to global styles & scripts
closes #4288
1 parent 0df3f7c commit c7e655c

File tree

11 files changed

+82
-19
lines changed

11 files changed

+82
-19
lines changed

docs/documentation/stories/global-scripts.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ This is especially useful for legacy libraries or analytic snippets.
1212
],
1313
```
1414

15-
You can also rename the output and lazy load it by using the object format:
15+
You can also use object format to do more advanced things:
16+
- `input` (required) - file path
17+
- `lazy` - flag to indicate if to lazy load it
18+
- `output` - the output bundle name
19+
- `env` - the environment to be included in
1620

1721
```json
1822
"scripts": [
1923
"global-script.js",
2024
{ "input": "lazy-script.js", "lazy": true },
2125
{ "input": "pre-rename-script.js", "output": "renamed-script" },
26+
{ "input": "production-script.js", "env": "prod" }
2227
],
2328
```

docs/documentation/stories/global-styles.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,19 @@ These will be loaded exactly as if you had added them in a `<link>` tag inside `
1616
],
1717
```
1818

19-
You can also rename the output and lazy load it by using the object format:
19+
You can also use object format to do more advanced things:
20+
- `input` (required) - file path
21+
- `lazy` - flag to indicate if to lazy load it
22+
- `output` - the output bundle name
23+
- `env` - the environment to be included in
2024

2125
```json
2226
"styles": [
2327
"styles.css",
2428
"more-styles.css",
2529
{ "input": "lazy-style.scss", "lazy": true },
2630
{ "input": "pre-rename-style.scss", "output": "renamed-style" },
31+
{ "input": "production-style.scss", "env": "prod" }
2732
],
2833
```
2934

packages/@angular/cli/lib/config/schema.json

+30-1
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,26 @@
126126
"type": "object",
127127
"properties": {
128128
"input": {
129+
"description": "The file path.",
130+
"type": "string"
131+
},
132+
"lazy": {
133+
"description": "Flag to indicate if it's lazy loaded.",
134+
"type": "boolean"
135+
},
136+
"output": {
137+
"description": "The output bundle name.",
138+
"type": "string"
139+
},
140+
"env": {
141+
"description": "The environment to be included in.",
129142
"type": "string"
130143
}
131144
},
132-
"additionalProperties": true
145+
"additionalProperties": true,
146+
"required": [
147+
"input"
148+
]
133149
}
134150
]
135151
},
@@ -162,6 +178,19 @@
162178
"type": "object",
163179
"properties": {
164180
"input": {
181+
"description": "The file path.",
182+
"type": "string"
183+
},
184+
"lazy": {
185+
"description": "Flag to indicate if it's lazy loaded.",
186+
"type": "boolean"
187+
},
188+
"output": {
189+
"description": "The output bundle name.",
190+
"type": "string"
191+
},
192+
"env": {
193+
"description": "The environment to be included in.",
165194
"type": "string"
166195
}
167196
},

packages/@angular/cli/models/webpack-configs/browser.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ export function getBrowserConfig(wco: WebpackConfigOptions) {
1818

1919
// figure out which are the lazy loaded entry points
2020
const lazyChunks = lazyChunksFilter([
21-
...extraEntryParser(appConfig.scripts, appRoot, 'scripts'),
22-
...extraEntryParser(appConfig.styles, appRoot, 'styles')
21+
...extraEntryParser(appConfig.scripts, appRoot, 'scripts', buildOptions.environment),
22+
...extraEntryParser(appConfig.styles, appRoot, 'styles', buildOptions.environment)
2323
]);
2424

2525
if (buildOptions.vendorChunk) {
@@ -35,7 +35,7 @@ export function getBrowserConfig(wco: WebpackConfigOptions) {
3535
new HtmlWebpackPlugin({
3636
template: path.resolve(appRoot, appConfig.index),
3737
filename: path.resolve(buildOptions.outputPath, appConfig.index),
38-
chunksSortMode: packageChunkSort(appConfig),
38+
chunksSortMode: packageChunkSort(appConfig, buildOptions.environment),
3939
excludeChunks: lazyChunks,
4040
xhtml: true
4141
}),

packages/@angular/cli/models/webpack-configs/common.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
4242

4343
// process global scripts
4444
if (appConfig.scripts.length > 0) {
45-
const globalScripts = extraEntryParser(appConfig.scripts, appRoot, 'scripts');
45+
const globalScripts = extraEntryParser(appConfig.scripts, appRoot, 'scripts',
46+
buildOptions.environment);
4647

4748
// add entry points and lazy chunks
4849
globalScripts.forEach(script => {

packages/@angular/cli/models/webpack-configs/styles.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ export function getStylesConfig(wco: WebpackConfigOptions) {
9999

100100
// process global styles
101101
if (appConfig.styles.length > 0) {
102-
const globalStyles = extraEntryParser(appConfig.styles, appRoot, 'styles');
102+
const globalStyles = extraEntryParser(appConfig.styles, appRoot, 'styles',
103+
buildOptions.environment);
104+
103105
// add style entry points
104106
globalStyles.forEach(style =>
105107
entryPoints[style.entry]

packages/@angular/cli/models/webpack-configs/utils.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface ExtraEntry {
3838
lazy?: boolean;
3939
path?: string;
4040
entry?: string;
41+
env?: string;
4142
}
4243

4344
// Filter extra entries out of a arran of extraEntries
@@ -51,7 +52,8 @@ export function lazyChunksFilter(extraEntries: ExtraEntry[]) {
5152
export function extraEntryParser(
5253
extraEntries: (string | ExtraEntry)[],
5354
appRoot: string,
54-
defaultEntry: string
55+
defaultEntry: string,
56+
environment: string
5557
): ExtraEntry[] {
5658
return extraEntries
5759
.map((extraEntry: string | ExtraEntry) =>
@@ -66,7 +68,8 @@ export function extraEntryParser(
6668
extraEntry.entry = defaultEntry;
6769
}
6870
return extraEntry;
69-
});
71+
})
72+
.filter(extraEntry => !extraEntry.env || extraEntry.env === environment);
7073
}
7174

7275
export interface HashFormat {

packages/@angular/cli/plugins/karma.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ const init: any = (config: any) => {
119119

120120
// Add global scripts. This logic mimics the one in webpack-configs/common.
121121
if (appConfig.scripts && appConfig.scripts.length > 0) {
122-
const globalScriptPatterns = extraEntryParser(appConfig.scripts, appRoot, 'scripts')
122+
const globalScriptPatterns = extraEntryParser(appConfig.scripts, appRoot, 'scripts',
123+
testConfig.environment)
123124
// Neither renamed nor lazy scripts are currently supported
124125
.filter(script => !(script.output || script.lazy))
125126
.map(script => ({ pattern: path.resolve(appRoot, script.input) }));

packages/@angular/cli/utilities/package-chunk-sort.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { ExtraEntry, extraEntryParser } from '../models/webpack-configs/utils';
22

33
// Sort chunks according to a predefined order:
44
// inline, polyfills, all scripts, all styles, vendor, main
5-
export function packageChunkSort(appConfig: any) {
5+
export function packageChunkSort(appConfig: any, environment: string) {
66
let entryPoints = ['inline', 'polyfills', 'sw-register'];
77

88
const pushExtraEntries = (extraEntry: ExtraEntry) => {
@@ -12,11 +12,11 @@ export function packageChunkSort(appConfig: any) {
1212
};
1313

1414
if (appConfig.scripts) {
15-
extraEntryParser(appConfig.scripts, './', 'scripts').forEach(pushExtraEntries);
15+
extraEntryParser(appConfig.scripts, './', 'scripts', environment).forEach(pushExtraEntries);
1616
}
1717

1818
if (appConfig.styles) {
19-
extraEntryParser(appConfig.styles, './', 'styles').forEach(pushExtraEntries);
19+
extraEntryParser(appConfig.styles, './', 'styles', environment).forEach(pushExtraEntries);
2020
}
2121

2222
entryPoints.push(...['vendor', 'main']);

tests/e2e/tests/build/scripts-array.ts

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import {
22
writeMultipleFiles,
33
expectFileToMatch,
4-
appendToFile
4+
appendToFile,
5+
expectFileToExist
56
} from '../../utils/fs';
67
import { ng } from '../../utils/process';
78
import { updateJsonFile } from '../../utils/project';
9+
import { expectToFail } from '../../utils/utils';
810
import { oneLineTrim } from 'common-tags';
911

1012
export default function () {
@@ -16,6 +18,8 @@ export default function () {
1618
'src/pre-rename-lazy-script.js': 'console.log(\'pre-rename-lazy-script\');',
1719
'src/common-entry-script.js': 'console.log(\'common-entry-script\');',
1820
'src/common-entry-style.css': '.common-entry-style { color: red }',
21+
'src/development-script.js': 'console.log(\'development-script\');',
22+
'src/production-script.js': 'console.log(\'production-script\');',
1923
})
2024
.then(() => appendToFile('src/main.ts', 'import \'./string-script.js\';'))
2125
.then(() => updateJsonFile('.angular-cli.json', configJson => {
@@ -26,7 +30,9 @@ export default function () {
2630
{ input: 'lazy-script.js', lazy: true },
2731
{ input: 'pre-rename-script.js', output: 'renamed-script' },
2832
{ input: 'pre-rename-lazy-script.js', output: 'renamed-lazy-script', lazy: true },
29-
{ input: 'common-entry-script.js', output: 'common-entry' }
33+
{ input: 'common-entry-script.js', output: 'common-entry' },
34+
{ input: 'development-script.js', output: 'development-script', env: 'dev' },
35+
{ input: 'production-script.js', output: 'production-script', env: 'prod' },
3036
];
3137
app['styles'] = [{ input: 'common-entry-style.css', output: 'common-entry' }];
3238
}))
@@ -39,6 +45,8 @@ export default function () {
3945
.then(() => expectFileToMatch('dist/renamed-lazy-script.bundle.js', 'pre-rename-lazy-script'))
4046
.then(() => expectFileToMatch('dist/common-entry.bundle.js', 'common-entry-script'))
4147
.then(() => expectFileToMatch('dist/common-entry.bundle.css', '.common-entry-style'))
48+
.then(() => expectFileToMatch('dist/development-script.bundle.js', 'development-script'))
49+
.then(() => expectToFail(() => expectFileToExist('dist/production-script.bundle.js')))
4250
// index.html lists the right bundles
4351
.then(() => expectFileToMatch('dist/index.html', oneLineTrim`
4452
<link href="common-entry.bundle.css" rel="stylesheet"/>
@@ -49,6 +57,7 @@ export default function () {
4957
<script type="text/javascript" src="scripts.bundle.js"></script>
5058
<script type="text/javascript" src="renamed-script.bundle.js"></script>
5159
<script type="text/javascript" src="common-entry.bundle.js"></script>
60+
<script type="text/javascript" src="development-script.bundle.js"></script>
5261
<script type="text/javascript" src="vendor.bundle.js"></script>
5362
<script type="text/javascript" src="main.bundle.js"></script>
5463
`))

tests/e2e/tests/build/styles/styles-array.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
writeMultipleFiles,
3-
expectFileToMatch
3+
expectFileToMatch,
4+
expectFileToExist
45
} from '../../../utils/fs';
56
import { ng } from '../../../utils/process';
67
import { updateJsonFile } from '../../../utils/project';
@@ -15,7 +16,9 @@ export default function () {
1516
'src/pre-rename-style.css': '.pre-rename-style { color: red }',
1617
'src/pre-rename-lazy-style.css': '.pre-rename-lazy-style { color: red }',
1718
'src/common-entry-style.css': '.common-entry-style { color: red }',
18-
'src/common-entry-script.js': 'console.log(\'common-entry-script\');'
19+
'src/common-entry-script.js': 'console.log(\'common-entry-script\');',
20+
'src/development-style.css': '.environment-style { color: blue }',
21+
'src/production-style.css': '.environment-style { color: green }',
1922
})
2023
.then(() => updateJsonFile('.angular-cli.json', configJson => {
2124
const app = configJson['apps'][0];
@@ -25,7 +28,9 @@ export default function () {
2528
{ input: 'lazy-style.css', lazy: true },
2629
{ input: 'pre-rename-style.css', output: 'renamed-style' },
2730
{ input: 'pre-rename-lazy-style.css', output: 'renamed-lazy-style', lazy: true },
28-
{ input: 'common-entry-style.css', output: 'common-entry' }
31+
{ input: 'common-entry-style.css', output: 'common-entry' },
32+
{ input: 'development-style.css', output: 'development-style', env: 'dev' },
33+
{ input: 'production-style.css', output: 'production-style', env: 'prod' },
2934
];
3035
app['scripts'] = [{ input: 'common-entry-script.js', output: 'common-entry' }];
3136
}))
@@ -38,11 +43,14 @@ export default function () {
3843
.then(() => expectFileToMatch('dist/renamed-lazy-style.bundle.css', '.pre-rename-lazy-style'))
3944
.then(() => expectFileToMatch('dist/common-entry.bundle.css', '.common-entry-style'))
4045
.then(() => expectFileToMatch('dist/common-entry.bundle.js', 'common-entry-script'))
46+
.then(() => expectFileToMatch('dist/development-style.bundle.css', '.environment-style'))
47+
.then(() => expectToFail(() => expectFileToExist('dist/production-style.bundle.css')))
4148
// index.html lists the right bundles
4249
.then(() => expectFileToMatch('dist/index.html', oneLineTrim`
4350
<link href="common-entry.bundle.css" rel="stylesheet"/>
4451
<link href="styles.bundle.css" rel="stylesheet"/>
4552
<link href="renamed-style.bundle.css" rel="stylesheet"/>
53+
<link href="development-style.bundle.css" rel="stylesheet"/>
4654
`))
4755
.then(() => expectFileToMatch('dist/index.html', oneLineTrim`
4856
<script type="text/javascript" src="inline.bundle.js"></script>

0 commit comments

Comments
 (0)