@@ -7,6 +7,7 @@ const path = require('path')
77const micromatch = require ( 'micromatch' )
88const W = require ( 'when' )
99const node = require ( 'when/node' )
10+ const File = require ( 'filewrap' )
1011const SingleEntryDependency = require ( 'webpack/lib/dependencies/SingleEntryDependency' )
1112const MultiEntryDependency = require ( 'webpack/lib/dependencies/MultiEntryDependency' )
1213
@@ -19,79 +20,83 @@ module.exports = class SpikeUtils {
1920 * Adds a number of files to webpack's pipeline as entires, so that webpack
2021 * processes them even if they are not required in the main js file.
2122 * @param {Object } compilation - object from plugin
22- * @param {Array } files - array of absolute paths to files
23+ * @param {Array|String } files - absolute path(s) to files
2324 * @return {Promise.<Array> } compilation.addEntry return value for each file
2425 */
2526 addFilesAsWebpackEntries ( compilation , files ) {
2627 return W . all ( Array . prototype . concat ( files ) . map ( ( f ) => {
27- const name = this . getOutputPath ( f )
28- const relativePath = f . replace ( this . conf . context , '.' )
29- const dep = new MultiEntryDependency ( [ new SingleEntryDependency ( relativePath ) ] , name )
28+ const file = new File ( this . conf . context , f )
29+ const dep = new MultiEntryDependency ( [ new SingleEntryDependency ( `./${ file . relative } ` ) ] , file . relative )
3030 const addEntryFn = compilation . addEntry . bind ( compilation )
3131
32- return node . call ( addEntryFn , this . conf . context , dep , name )
32+ return node . call ( addEntryFn , this . conf . context , dep , file . relative )
3333 } ) )
3434 }
3535
3636 /**
37- * Given a source file path, outputs the file's destination as spike
38- * will write it, relative to `public`.
37+ * Given a source file path, returns the path to the final output.
3938 * @param {String } file - path to source file
40- * @return {String } output path
39+ * @return {File } object containing relative and absolute paths
4140 */
42- getOutputPath ( file ) {
43- let rel = file . replace ( this . conf . context , '' )
41+ getOutputPath ( f ) {
42+ let file = new File ( this . conf . context , f )
4443
4544 this . conf . spike . dumpDirs . forEach ( ( d ) => {
46- const re = new RegExp ( `^${ path . sep } ${ d } ` )
47- if ( rel . match ( re ) ) { rel = rel . replace ( `${ path . sep } ${ d } ` , '' ) }
45+ const re = new RegExp ( `^${ d } \\${ path . sep } ` )
46+ if ( file . relative . match ( re ) ) {
47+ file = new File ( this . conf . output . path , file . relative . replace ( re , '' ) )
48+ }
4849 } )
4950
50- return rel . substring ( 1 )
51+ return file
52+ }
53+
54+ /**
55+ * Given a file's output path, returns the path to the source file.
56+ * @param {String } f - path to an output file, relative or absolute
57+ * @return {File } object containing relative and absolute paths
58+ */
59+ getSourcePath ( f ) {
60+ let file = new File ( this . conf . output . path , f )
61+
62+ // check to see if the file is from a dumpDir path
63+ // https://github.com/bcoe/nyc/issues/259
64+ /* istanbul ignore next */
65+ glob . sync ( `${ this . conf . context } /*(${ this . conf . spike . dumpDirs . join ( '|' ) } )/**` ) . forEach ( ( d ) => {
66+ const test = new RegExp ( file . relative )
67+ if ( d . match ( test ) ) file = new File ( this . conf . context , d )
68+ } )
69+
70+ return file
5171 }
5272
5373 /**
5474 * Removes assets from the webpack compilation, so that static files are not
5575 * written to the js file, since we already write them as static files.
76+ *
77+ * The `addFilesAsWebpackEntries` function uses the relative source path
78+ * to name files, and `this.conf.output.name` appends '.js' to the end, so
79+ * this is how the files appear in the compilation assets.
80+ *
81+ * As such, we transform the array of paths to ensure that we are getting a
82+ * relative source path, then append '.js' to the end. We then loop through
83+ * webpack's compilation assets and remove the ones we don't want to write.
84+ *
5685 * @param {Object } compilation - webpack compilation object from plugin
57- * @param {Array } _files - array of absolute paths to processed files
86+ * @param {Array|String } _files - path(s) to source files, relative/absolute
5887 * @param {Function } done - callback
5988 */
6089 removeAssets ( compilation , _files ) {
61- // assets are set in compilation.assets as the output path, relative to
62- // the root, with '.js' at the end, so we transform to that format for
63- // comparison
6490 let files = Array . prototype . concat ( _files ) . map ( ( f ) => {
65- return this . getOutputPath ( f ) . replace ( `${ this . conf . context } /` , '' ) + '.js'
91+ const file = new File ( this . conf . context , f )
92+ return `${ file . relative } .js`
6693 } )
67- // now we go through all the assets and remove the ones we have processed
68- // with spike so that they are not written to the js file
94+
6995 for ( const a in compilation . assets ) {
7096 if ( files . indexOf ( a ) > - 1 ) { delete compilation . assets [ a ] }
7197 }
7298 }
7399
74- /**
75- * Takes a relative path like `img/foo.png` and resolves it to an absolute
76- * path. Function respects your dumpDirs and knows how to resolve it's
77- * absolute source path.
78- * @param {String } file - a relative path
79- * @return {String } absolute path to the file
80- */
81- resolveRelativeSourcePath ( file ) {
82- let rel = file . replace ( this . conf . context , '' )
83-
84- // check to see if the file is from a dumpDir path
85- /* istanbul ignore next */
86- // https://github.com/bcoe/nyc/issues/259
87- glob . sync ( `${ this . conf . context } /*(${ this . conf . spike . dumpDirs . join ( '|' ) } )/**` ) . forEach ( ( d ) => {
88- const test = new RegExp ( rel )
89- if ( d . match ( test ) ) { rel = d }
90- } )
91-
92- return path . join ( rel )
93- }
94-
95100 /**
96101 * Boolean return whether a file matches any of the configured ignores.
97102 * @param {String } file - absolute file path
@@ -101,8 +106,24 @@ module.exports = class SpikeUtils {
101106 return micromatch . any ( file , this . conf . spike . ignore )
102107 }
103108
109+ /**
110+ * A shortcut to run a plugin on initialization in compile and watch mode.
111+ * @param {Compiler } compiler - webpack compiler instance from plugin
112+ * @param {Function } cb - function to be run in watch and compile mode
113+ */
104114 runAll ( compiler , cb ) {
105115 compiler . plugin ( 'run' , cb )
106116 compiler . plugin ( 'watch-run' , cb )
107117 }
118+
119+ /**
120+ * Micromatch alias for simple glob matching.
121+ * @param {Array } strings - array of strings to match against
122+ * @param {Array|String } patterns - glob patterns for matching
123+ * @param {Object } [options] - micromatch options
124+ * @return {Array } array of matching strings
125+ */
126+ matchGlobs ( ) {
127+ return micromatch . apply ( micromatch , arguments )
128+ }
108129}
0 commit comments