This repository has been archived by the owner on Jul 9, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #93 from WordPress/add/custom-templated-path-plugin
Package: Add `@wordpress/custom-templated-path-webpack-plugin` package
- Loading branch information
Showing
7 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# Custom Templated Path Webpack Plugin | ||
|
||
Webpack plugin for creating custom path template tags. Extend the [default set of template tags](https://webpack.js.org/configuration/output/#output-filename) with your own custom behavior. Hooks into Webpack's compilation process to allow you to replace tags with a substitute value. | ||
|
||
**Note:** This plugin targets Webpack 4.0 and newer, and is not compatible with older versions. | ||
|
||
## Usage | ||
|
||
Construct an instance of `CustomTemplatedPathPlugin` in your Webpack configurations `plugins` entry, passing an object where keys correspond to the template tag name. The value for each key is a function passed the original intended path and data corresponding to the asset. | ||
|
||
The following example creates a new `basename` tag to substitute the basename of each entry file in the build output file. When compiled, the built file will be output as `build-entry.js`. | ||
|
||
```js | ||
const { basename } = require( 'path' ); | ||
const CustomTemplatedPathPlugin = require( '@wordpress/custom-templated-path-webpack-plugin' ); | ||
|
||
module.exports = { | ||
// ... | ||
|
||
entry: './entry', | ||
|
||
output: { | ||
filename: 'build-[basename].js', | ||
}, | ||
|
||
plugins: [ | ||
new CustomTemplatedPathPlugin( { | ||
basename( path, data ) { | ||
let rawRequest; | ||
|
||
const entryModule = get( data, [ 'chunk', 'entryModule' ], {} ); | ||
switch ( entryModule.type ) { | ||
case 'javascript/auto': | ||
rawRequest = entryModule.rawRequest; | ||
break; | ||
|
||
case 'javascript/esm': | ||
rawRequest = entryModule.rootModule.rawRequest; | ||
break; | ||
} | ||
|
||
if ( rawRequest ) { | ||
return basename( rawRequest ); | ||
} | ||
|
||
return path; | ||
}, | ||
} ), | ||
], | ||
}; | ||
``` | ||
|
||
For more examples, refer to Webpack's own [`TemplatedPathPlugin.js`](https://github.com/webpack/webpack/blob/v4.1.1/lib/TemplatedPathPlugin.js), which implements the base set of template tags. |
33 changes: 33 additions & 0 deletions
33
packages/custom-templated-path-webpack-plugin/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "@wordpress/custom-templated-path-webpack-plugin", | ||
"version": "1.0.0", | ||
"description": "Webpack plugin for creating custom path template tags", | ||
"author": "WordPress", | ||
"license": "GPL-2.0-or-later", | ||
"keywords": [ | ||
"webpack", | ||
"webpack-plugin" | ||
], | ||
"homepage": "https://github.com/WordPress/packages/tree/master/packages/custom-templated-path-webpack-plugin/", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/WordPress/packages.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/WordPress/packages/issues" | ||
}, | ||
"main": "build/index.js", | ||
"module": "build-module/index.js", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"escape-string-regexp": "^1.0.5" | ||
}, | ||
"devDependencies": { | ||
"webpack": "^4.1.1" | ||
}, | ||
"peerDependencies": { | ||
"webpack": "^4.0.0" | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
packages/custom-templated-path-webpack-plugin/src/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
const escapeStringRegexp = require( 'escape-string-regexp' ); | ||
|
||
/** | ||
* Webpack plugin for handling specific template tags in Webpack configuration | ||
* values like those supported in the base Webpack functionality (e.g. `name`). | ||
* | ||
* @see webpack.TemplatedPathPlugin | ||
*/ | ||
class CustomTemplatedPathPlugin { | ||
/** | ||
* CustomTemplatedPathPlugin constructor. Initializes handlers as a tuple | ||
* set of RegExp, handler, where the regular expression is used in matching | ||
* a Webpack asset path. | ||
* | ||
* @param {Object.<string,Function>} handlers Object keyed by tag to match, | ||
* with function value returning | ||
* replacement string. | ||
*/ | ||
constructor( handlers ) { | ||
this.handlers = []; | ||
|
||
for ( const [ key, handler ] of Object.entries( handlers ) ) { | ||
const regexp = new RegExp( `\\[${ escapeStringRegexp( key ) }\\]`, 'gi' ); | ||
this.handlers.push( [ regexp, handler ] ); | ||
} | ||
} | ||
|
||
/** | ||
* Webpack plugin application logic. | ||
* | ||
* @param {Object} compiler Webpack compiler | ||
*/ | ||
apply( compiler ) { | ||
compiler.hooks.compilation.tap( 'CustomTemplatedPathPlugin', ( compilation ) => { | ||
compilation.mainTemplate.hooks.assetPath.tap( 'CustomTemplatedPathPlugin', ( path, data ) => { | ||
for ( let i = 0; i < this.handlers.length; i++ ) { | ||
const [ regexp, handler ] = this.handlers[ i ]; | ||
if ( regexp.test( path ) ) { | ||
return path.replace( regexp, handler( path, data ) ); | ||
} | ||
} | ||
|
||
return path; | ||
} ); | ||
} ); | ||
} | ||
} | ||
|
||
module.exports = CustomTemplatedPathPlugin; |
1 change: 1 addition & 0 deletions
1
packages/custom-templated-path-webpack-plugin/test/fixtures/.gitignore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
entry.js |
1 change: 1 addition & 0 deletions
1
packages/custom-templated-path-webpack-plugin/test/fixtures/entry/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = null; |
39 changes: 39 additions & 0 deletions
39
packages/custom-templated-path-webpack-plugin/test/fixtures/webpack.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
|
||
const { basename } = require( 'path' ); | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
|
||
const CustomTemplatedPathPlugin = require( '../../' ); | ||
|
||
module.exports = { | ||
mode: 'development', | ||
context: __dirname, | ||
entry: './entry', | ||
output: { | ||
filename: '[basename].js', | ||
path: __dirname, | ||
}, | ||
plugins: [ | ||
new CustomTemplatedPathPlugin( { | ||
basename( path, data ) { | ||
console.log(data) | ||
|
||
let rawRequest; | ||
if ( data && data.chunk && data.chunk.entryModule ) { | ||
rawRequest = data.chunk.entryModule.rawRequest; | ||
} | ||
|
||
if ( rawRequest ) { | ||
return basename( rawRequest ); | ||
} | ||
|
||
return path; | ||
}, | ||
} ), | ||
], | ||
}; |
34 changes: 34 additions & 0 deletions
34
packages/custom-templated-path-webpack-plugin/test/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
|
||
const path = require( 'path' ); | ||
const { promisify } = require( 'util' ); | ||
const webpack = promisify( require( 'webpack' ) ); | ||
const fs = require( 'fs' ); | ||
const access = promisify( fs.access ); | ||
const unlink = promisify( fs.unlink ); | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
|
||
const config = require( './fixtures/webpack.config.js' ); | ||
const CustomTemplatedPathPlugin = require( '../' ); | ||
|
||
describe( 'CustomTemplatedPathPlugin', () => { | ||
const outputFile = path.join( __dirname, '/fixtures/entry.js' ) | ||
|
||
beforeAll( async () => { | ||
// Remove output file so as not to report false positive from previous | ||
// test. Absorb error since the file may not exist (unlink will throw). | ||
try { | ||
await unlink( outputFile ); | ||
} catch ( error ) {} | ||
} ); | ||
|
||
it( 'should resolve with basename output', async () => { | ||
const stats = await webpack( config ); | ||
await access( outputFile ); | ||
} ); | ||
} ); |