Add block related assets entry points to product editor build (#37318)

* Add editorStyle properties to blocks

* Rename style.scss files to editor.scss

* Get block entry points for block related assets

* Copy block assets to core assets build folder

* Remove unusable dependency

* Add changelog entries

* Fix up RTL style builds for block assets

* Update copy-webpack-plugin dependency and lock file

* Fix up lock file after rebase

* Fix order of webpack rtl stylesheet builds to prevent additional stylsheets

* Fix up lock file after rebase

* Fix tsconfig
This commit is contained in:
Joshua T Flowers 2023-03-31 10:36:40 -07:00 committed by GitHub
parent e553759ab6
commit 85080f642b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 392 additions and 389 deletions

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add block related assets entry points to build

View File

@ -0,0 +1,145 @@
/**
* External dependencies
*/
const fs = require( 'fs' );
const path = require( 'path' );
const { sync: glob } = require( 'fast-glob' );
const srcDir = path.resolve( process.cwd(), 'src' );
const blocksBuildDir = '/build/blocks';
/**
* Get all the block meta data files in the src directory.
*
* @return {string[]} Block file paths.
*/
const getBlockMetaDataFiles = () => {
return glob( `${ srcDir.replace( /\\/g, '/' ) }/**/block.json`, {
absolute: true,
} );
};
/**
* Get the block meta data from a block.json file.
*
* @param {string} filePath File path to block.json file.
* @return {Object} Block meta data.
*/
const getBlockMetaData = ( filePath ) => {
return JSON.parse( fs.readFileSync( filePath ) );
};
/**
* Get the block file assets with raw file paths.
*
* @param {Object} blockMetaData
* @return {string[]} Asset file paths.
*/
const getBlockFileAssets = ( blockMetaData ) => {
const { editorScript, script, viewScript, style, editorStyle } =
blockMetaData;
return [ editorScript, script, viewScript, style, editorStyle ]
.flat()
.filter(
( rawFilepath ) => rawFilepath && rawFilepath.startsWith( 'file:' )
);
};
/**
* Get the block name from the meta data, removing the `woocommerce/` namespace.
*
* @param {Object} blockMetaData
* @return {string} Block name.
*/
const getBlockName = ( blockMetaData ) => {
return blockMetaData.name.split( '/' ).at( 1 );
};
/**
* Get the entry point name.
*
* @param {string} entryFilePath
* @param {Object} blockMetaData
* @return {string} The entry point name.
*/
const getEntryPointName = ( entryFilePath, blockMetaData ) => {
const filePathParts = entryFilePath.split( '/' );
filePathParts[ filePathParts.length - 2 ] = getBlockName( blockMetaData );
return filePathParts
.join( '/' )
.replace( srcDir, blocksBuildDir )
.replace( '/components', '' );
};
/**
* Get the entry file path.
*
* @param {string} rawFilepath Raw file path from the block.json file.
* @param {*} dir The directory the block exists in.
* @return {string} Entry file path.
*/
const getEntryFilePath = ( rawFilepath, dir ) => {
const filepath = path.join( dir, rawFilepath.replace( 'file:', '' ) );
return filepath
.replace( path.extname( filepath ), '' )
.replace( /\\/g, '/' );
};
/**
* Gets the absolute file path based on the entry file path, including the extension.
*
* @param {string} entryFilePath Entry file path.
* @return {string} Absolute file path.
*/
const getAbsoluteEntryFilePath = ( entryFilePath ) => {
const [ absoluteEntryFilepath ] = glob(
`${ entryFilePath }.([jt]s?(x)|?(s)css)`,
{
absolute: true,
}
);
return absoluteEntryFilepath;
};
/**
* Find all directories with block.json files and get entry points for block related assets.
*/
const blockEntryPoints = getBlockMetaDataFiles().reduce(
( accumulator, blockMetadataFile ) => {
const blockMetaData = getBlockMetaData( blockMetadataFile );
getBlockFileAssets( blockMetaData ).forEach( ( rawFilePath ) => {
const entryFilePath = getEntryFilePath(
rawFilePath,
path.dirname( blockMetadataFile )
);
const absoluteEntryFilepath =
getAbsoluteEntryFilePath( entryFilePath );
if ( ! absoluteEntryFilepath ) {
// eslint-disable-next-line no-console
console.warn( 'Block asset file not found.', entryFilePath );
return;
}
const entryPointName = getEntryPointName(
entryFilePath,
blockMetaData
);
accumulator[ entryPointName ] = absoluteEntryFilepath;
} );
return accumulator;
},
{}
);
module.exports = {
blocksBuildDir,
blockEntryPoints,
getBlockMetaData,
getEntryPointName,
};

View File

@ -89,6 +89,7 @@
"@wordpress/block-editor": "^9.8.0",
"@wordpress/browserslist-config": "wp-6.0",
"concurrently": "^7.0.0",
"copy-webpack-plugin": "^9.1.0",
"css-loader": "^3.6.0",
"eslint": "^8.32.0",
"jest": "^27.5.1",

View File

@ -20,5 +20,6 @@
"reusable": false,
"inserter": false,
"lock": false
}
},
"editorStyle": "file:./editor.css"
}

View File

@ -26,5 +26,6 @@
"reusable": false,
"inserter": false,
"lock": false
}
},
"editorStyle": "file:./editor.css"
}

View File

@ -25,5 +25,6 @@
"reusable": false,
"inserter": false,
"lock": false
}
},
"editorStyle": "file:./editor.css"
}

View File

@ -6,8 +6,8 @@
@import 'components/header/style.scss';
@import 'components/images/editor.scss';
@import 'components/block-editor/style.scss';
@import 'components/section/style.scss';
@import 'components/tab/style.scss';
@import 'components/section/editor.scss';
@import 'components/tab/editor.scss';
@import 'components/tabs/style.scss';
@import 'components/details-summary-block/style.scss';
@import 'components/product-mvp-ces-footer/style.scss';

View File

@ -1,7 +1,8 @@
{
"extends": "../tsconfig-cjs",
"include": [
"**/*",
"**/*.d.ts",
"src/**/*",
"src/**/*.json"
],
"compilerOptions": {

View File

@ -1,12 +1,29 @@
/**
* External dependencies
*/
const CopyWebpackPlugin = require( 'copy-webpack-plugin' );
const MiniCssExtractPlugin = require( 'mini-css-extract-plugin' );
const path = require( 'path' );
const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' );
const WebpackRTLPlugin = require( 'webpack-rtl-plugin' );
/**
* Internal dependencies
*/
const { webpackConfig } = require( '@woocommerce/internal-style-build' );
const {
blockEntryPoints,
getBlockMetaData,
getEntryPointName,
} = require( './config/block-entry-points' );
const NODE_ENV = process.env.NODE_ENV || 'development';
module.exports = {
mode: process.env.NODE_ENV || 'development',
entry: {
'build-style': __dirname + '/src/style.scss',
...blockEntryPoints,
},
output: {
path: __dirname,
@ -15,5 +32,42 @@ module.exports = {
parser: webpackConfig.parser,
rules: webpackConfig.rules,
},
plugins: webpackConfig.plugins,
plugins: [
new RemoveEmptyScriptsPlugin(),
new MiniCssExtractPlugin( {
filename: ( data ) => {
return data.chunk.name.startsWith( '/build/blocks' )
? `[name].css`
: `[name]/style.css`;
},
chunkFilename: 'chunks/[id].style.css',
} ),
new WebpackRTLPlugin( {
test: /(?<!style)\.css$/,
filename: '[name]-rtl.css',
minify: NODE_ENV === 'development' ? false : { safe: true },
} ),
new WebpackRTLPlugin( {
test: /style\.css$/,
filename: '[name]/style-rtl.css',
minify: NODE_ENV === 'development' ? false : { safe: true },
} ),
new CopyWebpackPlugin( {
patterns: [
{
from: './src/**/block.json',
to( { absoluteFilename } ) {
const blockMetaData = getBlockMetaData(
path.resolve( __dirname, absoluteFilename )
);
const entryPointName = getEntryPointName(
absoluteFilename,
blockMetaData
);
return `./${ entryPointName }`;
},
},
],
} ),
],
};

View File

@ -2,6 +2,7 @@
* External dependencies
*/
const { get } = require( 'lodash' );
const fs = require( 'fs' );
const path = require( 'path' );
const CopyWebpackPlugin = require( 'copy-webpack-plugin' );
const CustomTemplatedPathPlugin = require( '@wordpress/custom-templated-path-webpack-plugin' );
@ -193,6 +194,17 @@ const webpackConfig = {
force: true,
} ) ),
} ),
// Get all product editor blocks so they can be loaded via JSON.
new CopyWebpackPlugin( {
patterns: [
{
from: '../../packages/js/product-editor/build/blocks',
to: './product-editor/blocks',
},
],
} ),
// React Fast Refresh.
! isProduction && isHot && new ReactRefreshWebpackPlugin(),

View File

@ -0,0 +1,4 @@
Significance: minor
Type: add
Add product editor blocks to assets build folder

File diff suppressed because it is too large Load Diff