Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-use webpack and babel config for build script #12685

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
23,277 changes: 13,014 additions & 10,263 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 4 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,10 @@
"@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot",
"@wordpress/babel-preset-default": "file:packages/babel-preset-default",
"@wordpress/browserslist-config": "file:packages/browserslist-config",
"@wordpress/custom-templated-path-webpack-plugin": "file:packages/custom-templated-path-webpack-plugin",
"@wordpress/build-config": "file:packages/build-config",
"@wordpress/eslint-config": "file:packages/eslint-config",
"@wordpress/jest-console": "file:packages/jest-console",
"@wordpress/jest-preset-default": "file:packages/jest-preset-default",
"@wordpress/library-export-default-webpack-plugin": "file:packages/library-export-default-webpack-plugin",
"@wordpress/npm-package-json-lint-config": "file:packages/npm-package-json-lint-config",
"@wordpress/postcss-themes": "file:packages/postcss-themes",
"@wordpress/scripts": "file:packages/scripts",
Expand Down Expand Up @@ -107,10 +106,7 @@
"symlink-or-copy": "1.2.0",
"uuid": "3.3.2",
"webpack": "4.8.3",
"webpack-bundle-analyzer": "3.0.2",
"webpack-cli": "2.1.3",
"webpack-livereload-plugin": "2.1.1",
"webpack-rtl-plugin": "github:yoavf/webpack-rtl-plugin#develop"
"webpack-cli": "2.1.3"
},
"npmPackageJsonLintConfig": {
"extends": "@wordpress/npm-package-json-lint-config",
Expand Down Expand Up @@ -142,8 +138,8 @@
"scripts": {
"prebuild": "npm run check-engines",
"clean:packages": "rimraf ./packages/*/build ./packages/*/build-module ./packages/*/build-style",
"prebuild:packages": "npm run clean:packages && lerna run build && cross-env INCLUDE_PACKAGES=babel-plugin-import-jsx-pragma,postcss-themes,jest-console SKIP_JSX_PRAGMA_TRANSFORM=1 node ./bin/packages/build.js",
"build:packages": "cross-env EXCLUDE_PACKAGES=babel-plugin-import-jsx-pragma,jest-console,postcss-themes node ./bin/packages/build.js",
"prebuild:packages": "npm run clean:packages && lerna run build && cross-env INCLUDE_PACKAGES=babel-plugin-import-jsx-pragma,postcss-themes,jest-console,build-config SKIP_JSX_PRAGMA_TRANSFORM=1 node ./bin/packages/build.js",
gziolo marked this conversation as resolved.
Show resolved Hide resolved
"build:packages": "cross-env EXCLUDE_PACKAGES=babel-plugin-import-jsx-pragma,jest-console,postcss-themes,build-config node ./bin/packages/build.js",
"build": "npm run build:packages && cross-env NODE_ENV=production webpack",
"check-engines": "check-node-version --package",
"check-licenses": "concurrently \"wp-scripts check-licenses --prod --gpl2\" \"wp-scripts check-licenses --dev\"",
Expand Down
2 changes: 2 additions & 0 deletions packages/build-config/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build Config

168 changes: 168 additions & 0 deletions packages/build-config/config/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/**
* External dependencies
*/
const WebpackRTLPlugin = require( 'webpack-rtl-plugin' );
const LiveReloadPlugin = require( 'webpack-livereload-plugin' );

const { get } = require( 'lodash' );
const { basename } = require( 'path' );

const { BundleAnalyzerPlugin } = require( 'webpack-bundle-analyzer' );

/**
* WordPress dependencies
*/
const CustomTemplatedPathPlugin = require( '@wordpress/custom-templated-path-webpack-plugin' );
const LibraryExportDefaultPlugin = require( '@wordpress/library-export-default-webpack-plugin' );

/**
* Given a string, returns a new string with dash separators converted to
* camelCase equivalent. This is not as aggressive as `_.camelCase` in
* converting to uppercase, where Lodash will also capitalize letters
* following numbers.
*
* @param {string} string Input dash-delimited string.
*
* @return {string} Camel-cased string.
*/
function camelCaseDash( string ) {
return string.replace(
/-([a-z])/g,
( match, letter ) => letter.toUpperCase()
);
}

/**
* Converts @wordpress require into window reference
*
* Note this isn't the same as camel case because of the
* way that numbers don't trigger the capitalized next letter
*
* @example
* wordpressRequire( '@wordpress/api-fetch' ) = 'wp.apiFetch'
* wordpressRequire( '@wordpress/i18n' ) = 'wp.i18n'
*
* @param {string} request import name
* @return {string} global variable reference for import
*/
const wordpressRequire = ( request ) => {
// @wordpress/components -> [ @wordpress, components ]
const [ , name ] = request.split( '/' );

// components -> wp.components
return `wp.${ name.replace( /-([a-z])/g, ( match, letter ) => letter.toUpperCase() ) }`;
};

const wordpressExternals = ( context, request, callback ) =>
Copy link
Member

Choose a reason for hiding this comment

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

Does it magically detect all imports starting with @wordpress/* and converts them into externals?

Would it make sense to apply all improvements to the config as its own PR first so we could test them in isolation?

/^@wordpress\//.test( request ) ?
callback( null, `root ${ wordpressRequire( request ) }` ) :
callback();

const externals = [
{
react: 'React',
'react-dom': 'ReactDOM',
tinymce: 'tinymce',
moment: 'moment',
jquery: 'jQuery',
lodash: 'lodash',
'lodash-es': 'lodash',
electron: 'electron',
gziolo marked this conversation as resolved.
Show resolved Hide resolved
wp: 'wp',
},
wordpressExternals,
];

const isProduction = process.env.NODE_ENV === 'production';
const mode = isProduction ? 'production' : 'development';

const config = {
mode,
output: {
filename: './build/[basename]/index.js',
path: process.cwd(),
library: [ 'wp', '[name]' ],
libraryTarget: 'this',
},
externals,
resolve: {
modules: [
__dirname,
'node_modules',
],
alias: {
'lodash-es': 'lodash',
},
},
module: {
rules: [
{
test: /\.js$/,
use: [ 'source-map-loader' ],
enforce: 'pre',
},
{
test: /\.js$/,
exclude: [
/block-serialization-spec-parser/,
Copy link
Member

Choose a reason for hiding this comment

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

We should do something to make it more bullet-proof. I have no idea how it will behave outside of Gutenberg repository. It was a quick workaround to make ES5 modules with Webpack.

/is-shallow-equal/,
/node_modules/,
],
use: 'babel-loader',
},
],
},
plugins: [
// Create RTL files with a -rtl suffix
new WebpackRTLPlugin( {
suffix: '-rtl',
minify: process.env.NODE_ENV === 'production' ? { safe: true } : false,
} ),
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;
},
} ),
new LibraryExportDefaultPlugin( [
gziolo marked this conversation as resolved.
Show resolved Hide resolved
'api-fetch',
'deprecated',
'dom-ready',
'redux-routine',
'token-list',
].map( camelCaseDash ) ),
// GUTENBERG_BUNDLE_ANALYZER global variable enables utility that represents bundle content
// as convenient interactive zoomable treemap.
process.env.GUTENBERG_BUNDLE_ANALYZER && new BundleAnalyzerPlugin(),
// GUTENBERG_LIVE_RELOAD_PORT global variable changes port on which live reload works
// when running watch mode.
! isProduction && new LiveReloadPlugin( { port: process.env.GUTENBERG_LIVE_RELOAD_PORT || 35729 } ),
].filter( Boolean ),
stats: {
children: false,
},
};

if ( ! isProduction ) {
// GUTENBERG_DEVTOOL global variable controls how source maps are generated.
// See: https://webpack.js.org/configuration/devtool/#devtool.
config.devtool = process.env.GUTENBERG_DEVTOOL || 'source-map';
}

module.exports = config;
6 changes: 6 additions & 0 deletions packages/build-config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const webpackConfig = require( './config/webpack.config.js' );

module.exports = {
webpackConfig,
};

88 changes: 88 additions & 0 deletions packages/build-config/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
{
"name": "@wordpress/build-config",
gziolo marked this conversation as resolved.
Show resolved Hide resolved
"version": "1.0.0",
"description": "WordPress JavaScript build configuration.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
"keywords": [
"wordpress",
"build",
"config"
],
"homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/build-config/README.md",
"repository": {
"type": "git",
"url": "https://github.com/WordPress/gutenberg.git"
},
"bugs": {
"url": "https://github.com/WordPress/gutenberg/issues"
},
"engines": {
"node": ">=8",
"npm": ">=6.0.0"
},
"files": [
"build",
gziolo marked this conversation as resolved.
Show resolved Hide resolved
"build-module"
],
"main": "build/index.js",
"module": "build-module/index.js",
"dependencies": {
"@babel/core": "7.0.0",
gziolo marked this conversation as resolved.
Show resolved Hide resolved
"@babel/runtime-corejs2": "7.0.0",
"@wordpress/babel-plugin-import-jsx-pragma": "file:../babel-plugin-import-jsx-pragma",
"@wordpress/babel-plugin-makepot": "file:../babel-plugin-makepot",
"@wordpress/babel-preset-default": "file:../babel-preset-default",
"@wordpress/browserslist-config": "file:../browserslist-config",
"@wordpress/custom-templated-path-webpack-plugin": "file:../custom-templated-path-webpack-plugin",
"@wordpress/eslint-config": "file:../eslint-config",
"@wordpress/jest-console": "file:../jest-console",
"@wordpress/jest-preset-default": "file:../jest-preset-default",
"@wordpress/library-export-default-webpack-plugin": "file:../library-export-default-webpack-plugin",
"@wordpress/npm-package-json-lint-config": "file:../npm-package-json-lint-config",
"@wordpress/postcss-themes": "file:../postcss-themes",
"autoprefixer": "8.2.0",
"babel-loader": "8.0.0",
"chalk": "2.4.1",
"check-node-version": "3.1.1",
"concurrently": "3.5.0",
"core-js": "2.5.7",
"cross-env": "3.2.4",
"deasync": "0.1.13",
"deep-freeze": "0.0.1",
"doctrine": "2.1.0",
"eslint-plugin-jest": "21.5.0",
"espree": "3.5.4",
"glob": "7.1.2",
"husky": "0.14.3",
"jest-puppeteer": "3.2.1",
"lerna": "3.4.3",
"lint-staged": "7.2.0",
"lodash": "4.17.10",
"mkdirp": "0.5.1",
"node-sass": "4.9.2",
"path-type": "3.0.0",
"pegjs": "0.10.0",
"phpegjs": "1.0.0-beta7",
"postcss-color-function": "4.0.1",
"puppeteer": "1.6.1",
"react-test-renderer": "16.6.3",
"rimraf": "2.6.2",
"rtlcss": "2.4.0",
"sass-loader": "6.0.7",
"source-map-loader": "0.2.3",
"sprintf-js": "1.1.1",
"stylelint": "9.5.0",
"stylelint-config-wordpress": "13.1.0",
"symlink-or-copy": "1.2.0",
"uuid": "3.3.2",
"webpack": "4.8.3",
"webpack-bundle-analyzer": "3.0.2",
"webpack-cli": "2.1.3",
"webpack-livereload-plugin": "2.1.1",
"webpack-rtl-plugin": "github:yoavf/webpack-rtl-plugin#develop"
},
"publishConfig": {
"access": "public"
}
}
2 changes: 2 additions & 0 deletions packages/scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
},
"dependencies": {
"@wordpress/babel-preset-default": "file:../babel-preset-default",
"@wordpress/build-config": "file:../build-config",
"@wordpress/jest-preset-default": "file:../jest-preset-default",
"@wordpress/npm-package-json-lint-config": "file:../npm-package-json-lint-config",
"babel-eslint": "8.0.3",
Expand All @@ -40,6 +41,7 @@
"eslint": "^4.19.1",
"jest": "^23.6.0",
"npm-package-json-lint": "^3.3.1",
"react-dev-utils": "^6.1.1",
"read-pkg-up": "^1.0.1",
"resolve-bin": "^0.4.0"
},
Expand Down
46 changes: 46 additions & 0 deletions packages/scripts/scripts/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const { webpackConfig } = require( '@wordpress/build-config' );

process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';

const webpack = require( 'webpack' );
const formatWebpackMessages = require( 'react-dev-utils/formatWebpackMessages' );

webpackConfig.module.rules.forEach(
Copy link
Member

Choose a reason for hiding this comment

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

See my PR: #12837.

I think we should tackle @wordpress/scripts separately. It would be awesome to expose Webpack config first.

( rule ) => {
if ( 'babel-loader' === rule.use ) {
delete rule.use;

rule.loader = 'babel-loader';

rule.options = {
presets: [
'@wordpress/babel-preset-default',
],
};
}
}
);

const compiler = webpack( webpackConfig );

compiler.run(
( err, stats ) => {
let messages;

if ( err && err.message ) {
messages = formatWebpackMessages( {
errors: [ err.message ],
warnings: [],
} );
} else {
messages = formatWebpackMessages(
stats.toJson( { all: false, warnings: true, errors: true } )
);
}

/*eslint no-console: ["error", { allow: ["log"] }] */
console.log( messages );
}
);

Loading