Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Build: Add Webpack plugin dirname tag transform
  • Loading branch information
aduth committed Feb 12, 2018
commit 6239d53c7c9a66193a8c50fb958ab5f2dc9c1d65
64 changes: 62 additions & 2 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
const webpack = require( 'webpack' );
const ExtractTextPlugin = require( 'extract-text-webpack-plugin' );
const WebpackRTLPlugin = require( 'webpack-rtl-plugin' );
const { reduce, escapeRegExp, get } = require( 'lodash' );
const { basename, dirname } = require( 'path' );

// Main CSS loader for everything but blocks..
const mainCSSExtractTextPlugin = new ExtractTextPlugin( {
filename: './[name]/build/style.css',
filename: './[dir]/build/style.css',
} );

// CSS loader for styles specific to block editing.
Expand Down Expand Up @@ -75,6 +77,54 @@ const externals = {
};
} );

/**
* 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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we plan to extract it and move to WordPress/packages at some point? It might be useful for other repositories.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we plan to extract it and move to WordPress/packages at some point? It might be useful for other repositories.

Yeah, seems like a generally useful plugin.

/**
* 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.
*
* @return {void}
*/
constructor( handlers ) {
this.handlers = reduce( handlers, ( result, handler, key ) => {
const regexp = new RegExp( `\\[${ escapeRegExp( key ) }\\]`, 'gi' );
return [ ...result, [ regexp, handler ] ];
}, [] );
}

/**
* Webpack plugin application logic.
*
* @param {Object} compiler Webpack compiler
*
* @return {void}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to explicitly document that function doesn't return anything? Wouldn't it enough to assume that a function by default doesn't return value?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need to explicitly document that function doesn't return anything? Wouldn't it enough to assume that a function by default doesn't return value?

There's some precedent of this in existing core documentation. In general I'd be inclined to agree with you that it could be omitted for undefined return, but I could also see an argument for consistency / explicitness. Maybe worth bringing up in tomorrow's JS meeting? 😉

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docs again? Count me in ❤️

*/
apply( compiler ) {
compiler.plugin( 'compilation', ( compilation ) => {
compilation.mainTemplate.plugin( 'asset-path', ( 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;
} );
} );
}
}

const config = {
entry: Object.assign(
entryPointNames.reduce( ( memo, entryPointName ) => {
Expand All @@ -87,7 +137,7 @@ const config = {
}, {} )
),
output: {
filename: '[name]/build/index.js',
filename: '[dir]/build/index.js',
path: __dirname,
library: [ 'wp', '[name]' ],
libraryTarget: 'this',
Expand Down Expand Up @@ -149,6 +199,16 @@ const config = {
minimize: process.env.NODE_ENV === 'production',
debug: process.env.NODE_ENV !== 'production',
} ),
new CustomTemplatedPathPlugin( {
dir( path, data ) {
const request = get( data, [ 'chunk', 'entryModule', 'request' ] );
if ( request ) {
return basename( dirname( request ) );
}

return path;
},
} ),
],
stats: {
children: false,
Expand Down