-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Build: Prepare build for more script modules #65064
Changes from all commits
5d13ba4
aa536c9
3d9e13d
e5972f7
e3b2be7
bef8955
3e90adc
5080eb2
2185fd5
b924b55
29fcea4
df34883
73d9b5e
5bf5899
f5e2162
30d64d3
0a71b7d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,13 @@ | |
"src/**/*.scss", | ||
"{src,build,build-module}/*/init.js" | ||
], | ||
"wpScriptModuleExports": { | ||
"./file/view": "./build-module/file/view.js", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It starts to look like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes! I think this is going to be a very good direction. It moves in the direction of exports, but doesn't switch all the packages immediately. It's also a custom field, and these are custom builds in general specific for use as WordPress Script Modules. It makes it clear that they're not intended for general consumption. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also think we can move in the direction of generating the entrypoints in a standard way by reading package.json files. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, it doesn't work 🙃 (I thought it did but I'm not sure why that was). Problems:
When entrypoints are to modules ( So I don't think actually using this field as webpack There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That sounds like a great first step with some thin compact layer in the webpack config that scans package.json files and produces entry points that are hardcoded today. For blocks you could eventually use pattern matching. |
||
"./image/view": "./build-module/image/view.js", | ||
"./navigation/view": "./build-module/navigation/view.js", | ||
"./query/view": "./build-module/query/view.js", | ||
"./search/view": "./build-module/search/view.js" | ||
}, | ||
"dependencies": { | ||
"@babel/runtime": "^7.16.0", | ||
"@wordpress/a11y": "file:../a11y", | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
const { join } = require( 'path' ); | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
const DependencyExtractionWebpackPlugin = require( '@wordpress/dependency-extraction-webpack-plugin' ); | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
const { baseConfig, plugins } = require( './shared' ); | ||
|
||
const WORDPRESS_NAMESPACE = '@wordpress/'; | ||
const { createRequire } = require( 'node:module' ); | ||
|
||
const rootURL = new URL( '..', `file://${ __dirname }` ); | ||
const fromRootRequire = createRequire( rootURL ); | ||
|
||
/** @type {Iterable<[string, string]>} */ | ||
const iterableDeps = Object.entries( | ||
fromRootRequire( './package.json' ).dependencies | ||
); | ||
|
||
/** @type {Map<string, string>} */ | ||
const gutenbergScriptModules = new Map(); | ||
for ( const [ packageName, versionSpecifier ] of iterableDeps ) { | ||
if ( | ||
! packageName.startsWith( WORDPRESS_NAMESPACE ) || | ||
! versionSpecifier.startsWith( 'file:' ) || | ||
packageName.startsWith( WORDPRESS_NAMESPACE + 'react-native' ) | ||
) { | ||
continue; | ||
} | ||
|
||
const packageRequire = createRequire( | ||
// Remove the leading "file:" specifier to build a package URL. | ||
new URL( `${ versionSpecifier.substring( 5 ) }/`, rootURL ) | ||
); | ||
|
||
const depPackageJson = packageRequire( './package.json' ); | ||
if ( ! Object.hasOwn( depPackageJson, 'wpScriptModuleExports' ) ) { | ||
continue; | ||
} | ||
|
||
const moduleName = packageName.substring( WORDPRESS_NAMESPACE.length ); | ||
let { wpScriptModuleExports } = depPackageJson; | ||
|
||
// Special handling for { "wpScriptModuleExports": "./build-module/index.js" }. | ||
if ( typeof wpScriptModuleExports === 'string' ) { | ||
wpScriptModuleExports = { '.': wpScriptModuleExports }; | ||
} | ||
|
||
if ( Object.getPrototypeOf( wpScriptModuleExports ) !== Object.prototype ) { | ||
throw new Error( 'wpScriptModuleExports must be an object' ); | ||
} | ||
|
||
for ( const [ exportName, exportPath ] of Object.entries( | ||
wpScriptModuleExports | ||
) ) { | ||
if ( typeof exportPath !== 'string' ) { | ||
throw new Error( 'wpScriptModuleExports paths must be strings' ); | ||
} | ||
|
||
if ( ! exportPath.startsWith( './' ) ) { | ||
throw new Error( | ||
'wpScriptModuleExports paths must start with "./"' | ||
); | ||
} | ||
|
||
const name = | ||
exportName === '.' ? 'index' : exportName.replace( /^\.\/?/, '' ); | ||
|
||
gutenbergScriptModules.set( | ||
`${ moduleName }/${ name }`, | ||
packageRequire.resolve( exportPath ) | ||
); | ||
} | ||
} | ||
|
||
module.exports = { | ||
...baseConfig, | ||
name: 'script-modules', | ||
entry: Object.fromEntries( gutenbergScriptModules.entries() ), | ||
experiments: { | ||
outputModule: true, | ||
}, | ||
output: { | ||
devtoolNamespace: 'wp', | ||
filename: './build-module/[name].min.js', | ||
library: { | ||
type: 'module', | ||
}, | ||
path: join( __dirname, '..', '..' ), | ||
environment: { module: true }, | ||
module: true, | ||
chunkFormat: 'module', | ||
asyncChunks: false, | ||
}, | ||
resolve: { | ||
extensions: [ '.js', '.ts', '.tsx' ], | ||
}, | ||
module: { | ||
rules: [ | ||
{ | ||
test: /\.(j|t)sx?$/, | ||
exclude: /node_modules/, | ||
use: [ | ||
{ | ||
loader: require.resolve( 'babel-loader' ), | ||
options: { | ||
cacheDirectory: | ||
process.env.BABEL_CACHE_DIRECTORY || true, | ||
babelrc: false, | ||
configFile: false, | ||
presets: [ | ||
'@babel/preset-typescript', | ||
'@babel/preset-react', | ||
], | ||
}, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
plugins: [ ...plugins, new DependencyExtractionWebpackPlugin() ], | ||
watchOptions: { | ||
ignored: [ '**/node_modules' ], | ||
aggregateTimeout: 500, | ||
}, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't remember why there was pattern matching used for files in the
build
folder. @youknowriad, is there anything important we might miss when including the entirebuild-module
? At the moment, we want all files to be included from there.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created related PR #65064