1
1
import { spawn } from 'child_process' ;
2
- import { existsSync , statSync , copySync , writeFileSync } from 'fs-extra' ;
3
- import { join } from 'path' ;
2
+ import { existsSync , statSync , copySync , writeFileSync , readFileSync } from 'fs-extra' ;
3
+ import { join , basename } from 'path' ;
4
4
import { task , src , dest } from 'gulp' ;
5
5
import { execTask , sequenceTask } from '../util/task_helpers' ;
6
6
import {
7
- DIST_RELEASE , DIST_BUNDLES , DIST_MATERIAL , COMPONENTS_DIR , LICENSE_BANNER
7
+ DIST_RELEASE , DIST_BUNDLES , DIST_MATERIAL , COMPONENTS_DIR , LICENSE_BANNER , DIST_ROOT
8
8
} from '../constants' ;
9
9
import * as minimist from 'minimist' ;
10
10
11
11
// There are no type definitions available for these imports.
12
- const gulpRename = require ( 'gulp-rename ' ) ;
12
+ const glob = require ( 'glob ' ) ;
13
13
14
14
/** Parse command-line arguments for release task. */
15
15
const argv = minimist ( process . argv . slice ( 3 ) ) ;
@@ -29,30 +29,40 @@ task('build:release', sequenceTask(
29
29
) ) ;
30
30
31
31
/** Task that combines intermediate build artifacts into the release package structure. */
32
- task ( ':package:release' , [
32
+ task ( ':package:release' , sequenceTask (
33
+ [ ':package:typings' , ':package:umd' , ':package:fesm' , ':package:assets' ] ,
34
+ ':inline-metadata-resources' ,
33
35
':package:metadata' ,
34
- ':package:typings' ,
35
- ':package:umd' ,
36
- ':package:fesm' ,
37
- ':package:assets'
38
- ] ) ;
36
+ ) ) ;
39
37
40
38
/** Copy metatadata.json and associated d.ts files to the root of the package structure. */
41
- task ( ':package:metadata' , [ ':package:fix-metadata' ] , ( ) => {
39
+ task ( ':package:metadata' , ( ) => {
42
40
// See: https://github.com/angular/angular/blob/master/build.sh#L293-L294
43
41
copySync ( join ( DIST_MATERIAL , 'index.metadata.json' ) ,
44
42
join ( DIST_RELEASE , 'material.metadata.json' ) ) ;
45
43
} ) ;
46
44
47
- /**
48
- * Workaround for a @angular/tsc-wrapped issue, where the compiler looks for component assets
49
- * in the wrong folder. This issue only appears for bundled metadata files.
50
- * As a workaround, we just copy all assets next to the metadata bundle.
51
- **/
52
- task ( ':package:fix-metadata' , ( ) => {
53
- return src ( '**/*.+(html|css)' , { cwd : DIST_MATERIAL } )
54
- . pipe ( gulpRename ( { dirname : '' } ) )
55
- . pipe ( dest ( DIST_RELEASE ) ) ;
45
+ /** Inlines the html and css resources into all metadata.json files in dist/ */
46
+ task ( ':inline-metadata-resources' , ( ) => {
47
+ // Create a map of fileName -> fullFilePath. This is needed because the templateUrl and
48
+ // styleUrls for each component use just the filename because, in the source, the component
49
+ // and the resources live in the same directory.
50
+ const componentResources = new Map < string , string > ( ) ;
51
+ glob ( join ( DIST_ROOT , '**/*.+(html|css)' ) , ( err : any , resourceFilePaths : any ) => {
52
+ for ( const path of resourceFilePaths ) {
53
+ componentResources . set ( basename ( path ) , path ) ;
54
+ }
55
+ } ) ;
56
+
57
+ // Find all metadata files. For each one, parse the JSON content, inline the resources, and
58
+ // reserialize and rewrite back to the original location.
59
+ glob ( join ( DIST_ROOT , '**/*.metadata.json' ) , ( err : any , metadataFilePaths : any ) => {
60
+ for ( const path of metadataFilePaths ) {
61
+ let metadata = JSON . parse ( readFileSync ( path , 'utf-8' ) ) ;
62
+ inlineMetadataResources ( metadata , componentResources ) ;
63
+ writeFileSync ( path , JSON . stringify ( metadata ) , 'utf-8' ) ;
64
+ }
65
+ } ) ;
56
66
} ) ;
57
67
58
68
task ( ':package:assets' , ( ) => src ( assetsGlob ) . pipe ( dest ( DIST_RELEASE ) ) ) ;
@@ -155,3 +165,36 @@ task('publish', sequenceTask(
155
165
':publish' ,
156
166
':publish:logout' ,
157
167
) ) ;
168
+
169
+
170
+ /**
171
+ * Recurse through a parsed metadata.json file and inline all html and css.
172
+ * Note: this assumes that all html and css files have a unique name.
173
+ */
174
+ function inlineMetadataResources ( metadata : any , componentResources : Map < string , string > ) {
175
+ // Convert `templateUrl` to `template`
176
+ if ( metadata . templateUrl ) {
177
+ const fullResourcePath = componentResources . get ( metadata . templateUrl ) ;
178
+ metadata . template = readFileSync ( fullResourcePath , 'utf-8' ) ;
179
+ delete metadata . templateUrl ;
180
+ }
181
+
182
+ // Convert `styleUrls` to `styles`
183
+ if ( metadata . styleUrls && metadata . styleUrls . length ) {
184
+ metadata . styles = [ ] ;
185
+ for ( const styleUrl of metadata . styleUrls ) {
186
+ const fullResourcePath = componentResources . get ( styleUrl ) ;
187
+ metadata . styles . push ( readFileSync ( fullResourcePath , 'utf-8' ) ) ;
188
+ }
189
+ delete metadata . styleUrls ;
190
+ }
191
+
192
+ // We we did nothing at this node, go deeper.
193
+ if ( ! metadata . template && ! metadata . styles ) {
194
+ for ( const property in metadata ) {
195
+ if ( typeof metadata [ property ] == 'object' && metadata [ property ] ) {
196
+ inlineMetadataResources ( metadata [ property ] , componentResources ) ;
197
+ }
198
+ }
199
+ }
200
+ }
0 commit comments