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

Generate minified .min.js and unminified .js files for GB js entry points when building #31732

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ea484fe
Add .min.js suffix to index script depending on the presence of env v…
fullofcaffeine May 12, 2021
7d8c554
Decide what to enqueue depending on the value of the SCRIPT_DEBUG env…
fullofcaffeine May 12, 2021
7049cfa
WIP
fullofcaffeine May 20, 2021
0344474
Save unminified .js sources before minimizer runs
fullofcaffeine May 20, 2021
b793205
No need to pass the mode anymore
fullofcaffeine May 20, 2021
9333972
Add packaged version PoC and tests
fullofcaffeine May 21, 2021
11e6ee7
Package as internal monorepo npm, remove top-level PoC module
fullofcaffeine May 22, 2021
2f71f41
Merge branch 'trunk' into try/minified-and-unminified-entries-webpack…
fullofcaffeine May 22, 2021
fc04306
Add test artifacts
fullofcaffeine May 22, 2021
5276fe0
Use snake case for var, simplify and DRY the asset name
fullofcaffeine May 26, 2021
8e689a2
Hardcode index.min.js for override scripts
fullofcaffeine Jun 3, 2021
0db666d
Always refer to index.asset.php as the asset loader scripts
fullofcaffeine Jun 3, 2021
6bcdfc2
More reliable extension replacement
jsnajdr Jun 3, 2021
424e656
Fix lint error
fullofcaffeine Jun 4, 2021
ab42326
Fix php lint errors
fullofcaffeine Jun 4, 2021
27bb663
Fix another linter error (prefer-alphabetical-devDependencies)
fullofcaffeine Jun 4, 2021
e7df95e
Update packages/readable-js-assets-webpack-plugin/package.json
fullofcaffeine Jun 9, 2021
9ae5416
Update packages/readable-js-assets-webpack-plugin/README.md
fullofcaffeine Jun 9, 2021
e72e2fc
Add .nmprc and CHANGELOG.md
fullofcaffeine Jun 9, 2021
15fc75c
Restrict the compressed-size-action to *.min.js assets (and *.css)
fullofcaffeine Jun 9, 2021
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
2 changes: 1 addition & 1 deletion .github/workflows/bundle-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ jobs:
- uses: preactjs/compressed-size-action@7d87f60a6b0c7d193b8183ce859ed00b356ea92f # v2.1.0
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
pattern: '{build/**/*.js,build/**/*.css}'
pattern: '{build/**/*.min.js,build/**/*.css}'
6 changes: 6 additions & 0 deletions docs/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1679,6 +1679,12 @@
"markdown_source": "../packages/react-native-editor/README.md",
"parent": "packages"
},
{
"title": "@wordpress/readable-js-assets-webpack-plugin",
"slug": "packages-readable-js-assets-webpack-plugin",
"markdown_source": "../packages/readable-js-assets-webpack-plugin/README.md",
"parent": "packages"
},
{
"title": "@wordpress/redux-routine",
"slug": "packages-redux-routine",
Expand Down
11 changes: 6 additions & 5 deletions lib/client-assets.php
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ function gutenberg_override_translation_file( $file, $handle ) {
}

// Ignore scripts that are not found in the expected `build/` location.
$script_path = gutenberg_dir_path() . 'build/' . substr( $handle, 3 ) . '/index.js';
$script_path = gutenberg_dir_path() . 'build/' . substr( $handle, 3 ) . '/index.min.js';
if ( ! file_exists( $script_path ) ) {
return $file;
}
Expand Down Expand Up @@ -236,14 +236,15 @@ function gutenberg_register_packages_scripts( $scripts ) {
// When in production, use the plugin's version as the default asset version;
// else (for development or test) default to use the current time.
$default_version = defined( 'GUTENBERG_VERSION' ) && ! ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? GUTENBERG_VERSION : time();
$suffix = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '.js' : '.min.js';

foreach ( glob( gutenberg_dir_path() . 'build/*/index.js' ) as $path ) {
foreach ( glob( gutenberg_dir_path() . "build/*/index$suffix" ) as $path ) {
// Prefix `wp-` to package directory to get script handle.
// For example, `…/build/a11y/index.js` becomes `wp-a11y`.
// For example, `…/build/a11y/index.min.js` becomes `wp-a11y`.
$handle = 'wp-' . basename( dirname( $path ) );

// Replace `.js` extension with `.asset.php` to find the generated dependencies file.
$asset_file = substr( $path, 0, -3 ) . '.asset.php';
// Replace suffix and extension with `.asset.php` to find the generated dependencies file.
$asset_file = substr( $path, 0, -( strlen( $suffix ) ) ) . '.asset.php';
Copy link
Member Author

@fullofcaffeine fullofcaffeine Jun 3, 2021

Choose a reason for hiding this comment

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

We could hardcode index.asset.php here, but this approach required less changes, and I didn't want to change more than I needed in this context, at least not as part of this PR. Let me know what you think :)

Copy link
Member

Choose a reason for hiding this comment

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

There are asset files that are not index, e.g., frontend.asset.php for blocks. These are not used in this particular loop but who knows, someday they could. Being flexible sounds OK.

$asset = file_exists( $asset_file )
? require( $asset_file )
: null;
Expand Down
4 changes: 4 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@
"@wordpress/postcss-themes": "file:packages/postcss-themes",
"@wordpress/prettier-config": "file:packages/prettier-config",
"@wordpress/project-management-automation": "file:packages/project-management-automation",
"@wordpress/readable-js-assets-webpack-plugin": "file:packages/readable-js-assets-webpack-plugin",
"@wordpress/scripts": "file:packages/scripts",
"@wordpress/stylelint-config": "file:packages/stylelint-config",
"appium": "1.20.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ class DependencyExtractionWebpackPlugin {
}

const assetFilename = buildFilename.replace(
/\.js$/i,
/(\.min)?\.js$/i,
'.asset.' + ( outputFormat === 'php' ? 'php' : 'json' )
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,26 @@ Array [
]
`;

exports[`Webpack \`has-extension-suffix\` should produce expected output: Asset file should match snapshot 1`] = `"<?php return array('dependencies' => array('lodash', 'wp-blob'), 'version' => '99bd32161d8514cc8c0cb8b0543ace3f');"`;

exports[`Webpack \`has-extension-suffix\` should produce expected output: External modules should match snapshot 1`] = `
Array [
Object {
"externalType": "window",
"request": "lodash",
"userRequest": "lodash",
},
Object {
"externalType": "window",
"request": Array [
"wp",
"blob",
],
"userRequest": "@wordpress/blob",
},
]
`;

exports[`Webpack \`no-default\` should produce expected output: Asset file should match snapshot 1`] = `"<?php return array('dependencies' => array(), 'version' => '7cedfbba436728640c2c4961b598ab32');"`;

exports[`Webpack \`no-default\` should produce expected output: External modules should match snapshot 1`] = `Array []`;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* External dependencies
*/
import { isEmpty } from 'lodash';

/**
* WordPress dependencies
*/
import { isBlobURL } from '@wordpress/blob';

isEmpty( isBlobURL( '' ) );
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Internal dependencies
*/
const DependencyExtractionWebpackPlugin = require( '../../..' );

module.exports = {
output: {
filename: 'index.min.js',
},
plugins: [ new DependencyExtractionWebpackPlugin() ],
};
1 change: 1 addition & 0 deletions packages/readable-js-assets-webpack-plugin/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
5 changes: 5 additions & 0 deletions packages/readable-js-assets-webpack-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!-- Learn how to maintain this file at https://github.com/WordPress/gutenberg/tree/HEAD/packages#maintaining-changelogs. -->

## Unreleased

Initial release.
39 changes: 39 additions & 0 deletions packages/readable-js-assets-webpack-plugin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Readable JS assets WebPack Plugin

Generate a readable non-minified JS file for each `.min.js` asset.

The end result is that for each JS entrypoint, we get a set of readable and non-minimized `.js` file and a minimized `.min.js`. This allows Gutenberg to follow the WordPress convention of adding a `.min.js` suffix to minimized JS files, while still providing a readable and unminized files that play well with the WordPress i18n machinery.

Consult the [webpack website](https://webpack.js.org) for additional information on webpack concepts.

## Installation

Install the module

```bash
npm install @wordpress/readable-js-assets-webpack-plugin --save-dev
```

**Note**: This package requires Node.js 12.0.0 or later. It also requires webpack 4.8.3 and newer. It is not compatible with older versions.

## Usage

### Webpack

Use this plugin as you would other webpack plugins:

```js
// webpack.config.js
const ReadableJsAssetsWebpackPlugin = require( '@wordpress/readable-js-assets-webpack-plugin' );

module.exports = {
// …snip
plugins: [ new ReadableJsAssetsWebpackPlugin() ],
};
```

**Note:**
- Multiple instances of the plugin are not supported and may produced unexpected results;
- It assumes your webpack pipeline is already generating a `.min.js` JS asset file for each JS entry-point.

<br/><br/><p align="center"><img src="https://s.w.org/style/images/codeispoetry.png?1" alt="Code is Poetry." /></p>
41 changes: 41 additions & 0 deletions packages/readable-js-assets-webpack-plugin/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* External dependencies
*/
const fs = require( 'fs' );
const path = require( 'path' );

class AddReadableJsAssetsWebpackPlugin {
extractUnminifiedFiles( compilation ) {
const files = compilation.chunks.flatMap( ( chunk ) => chunk.files );
compilation.unminifiedAssets = files.map( ( file ) => {
const asset = compilation.assets[ file ];
const unminifiedFile = file.replace( /\.min\.js$/, '.js' );
return [ unminifiedFile, asset.source() ];
} );
}
async writeUnminifiedFiles( compilation ) {
for ( const [ file, source ] of compilation.unminifiedAssets ) {
await fs.promises.writeFile(
path.join( compilation.options.output.path, file ),
fullofcaffeine marked this conversation as resolved.
Show resolved Hide resolved
source
);
}
}
apply( compiler ) {
compiler.hooks.compilation.tap(
this.constructor.name,
( compilation ) => {
compilation.hooks.additionalAssets.tap(
this.constructor.name,
() => this.extractUnminifiedFiles( compilation )
);
}
);
compiler.hooks.afterEmit.tapPromise(
this.constructor.name,
( compilation ) => this.writeUnminifiedFiles( compilation )
);
}
}

module.exports = AddReadableJsAssetsWebpackPlugin;
36 changes: 36 additions & 0 deletions packages/readable-js-assets-webpack-plugin/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "@wordpress/readable-js-assets-webpack-plugin",
"version": "1.0.0-prerelease",
"description": "Generate a readable JS file for each JS asset.",
"author": "The WordPress Contributors",
"license": "GPL-2.0-or-later",
"keywords": [
"wordpress",
"gutenberg",
"webpack",
"readable",
"minimizer"
],
"homepage": "https://github.com/WordPress/gutenberg/tree/HEAD/packages/readable-js-assets-webpack-plugin/README.md",
"repository": {
"type": "git",
"url": "https://github.com/WordPress/gutenberg.git",
"directory": "packages/readable-js-assets-webpack-plugin"
},
"bugs": {
"url": "https://github.com/WordPress/gutenberg/issues"
},
"engines": {
"node": ">=12.0"
},
"files": [
"index.js"
],
"main": "index.js",
"peerDependencies": {
"webpack": "^4.8.3 || ^5.0.0"
Copy link
Member

Choose a reason for hiding this comment

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

We'll need to update the plugin for webpack 5. Instead of the additionalAssets hook, we'll likely be hooking into something else. The terser-webpack-plugin also uses different hooks for v4 and v5.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, not sure I understood. Should we do this now or only when we migrate to v5? AFAIK we're still using v4.x, right?

},
"publishConfig": {
"access": "public"
}
}
Loading