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

wp-scripts with CSS only entry points? #54467

Open
chimok opened this issue Sep 14, 2023 · 5 comments
Open

wp-scripts with CSS only entry points? #54467

chimok opened this issue Sep 14, 2023 · 5 comments
Labels
[Tool] WP Scripts /packages/scripts [Type] Enhancement A suggestion for improvement.

Comments

@chimok
Copy link

chimok commented Sep 14, 2023

What problem does this address?

I'm using wp-scripts for my plugin. I have a folder block-mods contain only additional css loading for core blocks with PHP wp_enqueue_block_style function. Now the problem is my CSS use PostCSS and i would like to have some preprocessing, but how is it possible since its not included in block.json or any javascript?

What is your proposed solution?

I would like to see better customize options for wp-scripts, especially entry points, chunk names and PHP files to copy.
Maybe have a json configuration could be a option? Currently my workaround is using a custom webpack.config.js and I hope someone come up with a better idea?

@gziolo gziolo added the [Tool] WP Scripts /packages/scripts label Sep 14, 2023
@chimok
Copy link
Author

chimok commented Sep 15, 2023

I'm using postcss-cli for now because what I need is more like a task runner instead bundler.

npx postcss src/block-mods/**/*.css --base src/block-mods --dir build/block-mods

Anyway. I think this must be a quite common scenario for theme builders? Another thing I dislike is the filenames and chunks wp-scripts generates. It's always a big surprise what files finally come out in build. For example. I have a file index.js and it includes view.css and custom.css - I wish wp-scripts only creates a single css for anything included in index.js

@jordesign jordesign added the [Type] Enhancement A suggestion for improvement. label Sep 18, 2023
@benoitchantre
Copy link
Contributor

Here's what I use, based on https://gist.github.com/justintadlock/043f7fedb436a80174da27ee0c5fa53b

webpack.config.js

// WordPress webpack config.
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );

// Plugins.
const RemoveEmptyScriptsPlugin = require( 'webpack-remove-empty-scripts' );
const CopyPlugin = require( 'copy-webpack-plugin' );

// Utilities.
const path = require( 'path' );
const { globSync } = require( 'fast-glob' );

// Stylesheets entrypoints.
const stylesheetEntryPoints = () =>
	globSync( './assets/css/**/*.{css,scss}' ).reduce( ( files, filepath ) => {
		const relativePath = path.relative(
			path.resolve( process.cwd(), 'assets/css' ),
			filepath
		);

		// Exclude files that are already imported.
		if ( ! path.basename( filepath ).startsWith( '_' ) ) {
			const destinationPath = `../css/${ relativePath.replace(
				/\.(css|scss)$/,
				''
			) }`;
			files[ destinationPath ] = filepath;
		}

		return files;
	}, {} );

// Scripts entrypoints.
const scriptsEntryPoints = () =>
	globSync( './assets/js/**/*.js' ).reduce( ( files, filepath ) => {
		const relativePath = path.relative(
			path.resolve( process.cwd(), 'assets/js' ),
			filepath
		);

		// Exclude files that are already imported.
		if ( ! relativePath.startsWith( 'imports/' ) ) {
			const destinationPath = `../js/${ relativePath.replace(
				/\.js$/,
				''
			) }`;
			files[ destinationPath ] = filepath;
		}

		return files;
	}, {} );

module.exports = {
	...defaultConfig,
	...{
		entry: {
			...defaultConfig.entry(),
			...stylesheetEntryPoints(),
			...scriptsEntryPoints(),
		},
		plugins: [
			...defaultConfig.plugins,
			new RemoveEmptyScriptsPlugin( {
				stage: RemoveEmptyScriptsPlugin.STAGE_AFTER_PROCESS_PLUGINS,
			} ),
			new CopyPlugin( {
				patterns: [
					{ from: 'assets/fonts', to: '../fonts' },
					{ from: 'assets/images', to: '../images' },
				],
			} ),
		],
	},
};

package.json

{
	"devDependencies": {
		"@wordpress/scripts": "^26.16.0",
		"path": "^0.12.7",
		"webpack-remove-empty-scripts": "^1.0.4"
	},
	"prettier": "@wordpress/prettier-config",
	"scripts": {
		"build": "wp-scripts build --webpack-src-dir=blocks --output-path=dist/blocks --webpack-copy-php",
		"check-engines": "wp-scripts check-engines",
		"format": "wp-scripts format",
		"lint:css": "wp-scripts lint-style",
		"lint:js": "wp-scripts lint-js",
		"start": "wp-scripts start --webpack-src-dir=blocks --output-path=dist/blocks --webpack-copy-php"
	}
}

Maybe the @wordpress/scripts could include the remove empty scripts plugin and have additional flags to ease it's usage for themes assets like you describe (core blocks overrides or javascript files).

@gziolo
Copy link
Member

gziolo commented Nov 24, 2023

Maybe the @wordpress/scripts could include the remove empty scripts plugin and have additional flags to ease it's usage for themes assets like you describe (core blocks overrides or javascript files).

I left a comment on a similar topic today #55936 (comment). Let's explore how we can expand the automatic discovery of JS and CSS entry points for both plugins and themes in wp-scripts build. This tool can be flexible enough to support most of the developers in the community.

The only challenge would be arriving at the patterns for detecting CSS files. Are there any existing patterns?

@benoitchantre
Copy link
Contributor

This is not an exhaustive research, but it appears that assets is a common directory name.
I have ommitted styles.css which may contain styles or only the theme headers.

When people build bespoke themes and choose to include custom blocks in their theme, I don't know where they put their blocks. I would say either a blocks directory inside or next to the assets directory.

From https://github.com/10up/wp-scaffold/tree/trunk/themes/10up-theme/

|- assets/
|  |- css/
|  |- fonts/
|  |- images/
|  |- js/ 
|  |- svg/

From https://github.com/justintadlock/first-draft/

|- assets/
|  |- css/
|  |  |- blocks/            (core blocks overrides)
|  |- fonts/
|  |- img/
|  |- js/ 

From https://github.com/OllieWP/ollie

|- assets/
|  |- css/                  (core blocks overrides)
|  |- fonts/
|  |- images/

From https://github.com/wpengine/frost

|- assets/
|  |- fonts/
|  |- images/

From https://github.com/WordPress/twentytwentyfour/

|- assets/
|  |- fonts/
|  |- styles/               (core blocks overrides)

From https://github.com/WordPress/twentytwentyone/

|- assets/
|  |- css/                  (build files from the sass directory)
|  |- images/
|  |- js/
|  |- sass/

@chimok
Copy link
Author

chimok commented Feb 2, 2024

I use the same code then @benoitchantre but I found it in the gutenberg source. I think it would be already helpful if there is a simple helper function we can import in our webpack.config.js and set the glob path with a argument.

I believe the the assets/ folder is used for historical reasons? With a bundler prefer nowadays src/ and dist/ because it's clear if preprocessing is required. @gziolo For automatic detection, how about mystyle.block.css and searching anything with *.block.css?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Tool] WP Scripts /packages/scripts [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests

4 participants