Skip to content

Commit

Permalink
Merge branch 'develop' into feature/339-filename-based-entrypoint-for…
Browse files Browse the repository at this point in the history
…-block-specific-CSS
  • Loading branch information
dmtrmrv committed May 20, 2024
2 parents ab2197e + 6ca808b commit 1c01f08
Show file tree
Hide file tree
Showing 35 changed files with 375 additions and 56 deletions.
5 changes: 0 additions & 5 deletions .changeset/early-kiwis-arrive.md

This file was deleted.

16 changes: 0 additions & 16 deletions .changeset/pre.json

This file was deleted.

36 changes: 29 additions & 7 deletions package-lock.json

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

21 changes: 21 additions & 0 deletions packages/toolkit/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,26 @@
# Changelog

## 6.1.0

### Minor Changes

- a41a046: Add support for `scriptModule` & `viewScriptModule` assets
- 1693913: Bundle PostCSS Global Data Plugin with default configuration

### Patch Changes

- 20d2e65: Feature: allow defining module script entrypoints via `moduleEntry` key in `package.json` decoupled from blocks

## 6.1.0-next.1

### Minor Changes

- 1693913: Bundle PostCSS Global Data Plugin with default configuration

### Patch Changes

- 20d2e65: Feature: allow defining module script entrypoints via `moduleEntry` key in `package.json` decoupled from blocks

## 6.1.0-next.0

### Minor Changes
Expand Down
59 changes: 58 additions & 1 deletion packages/toolkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ Alternatively, you can set up `process.env.ASSET_PATH` to whatever path (or CDN)

_NOTE: Since 10up-toolkit@6 this `useBlockAssets` is on by default_

If your project includes blocks there are quite a few assets that need to be added to the list of entry points for Webpack to transpile. This can get quite cumbersome and repetitive. To make this easier toolkit has a special mode where it scans the source path for any `block.json` files and automatically adds any assets that are defined in there via the `script`, `editorScript`, `viewScript`, `style`, `editorStyle` keys with webpack.
If your project includes blocks there are quite a few assets that need to be added to the list of entry points for Webpack to transpile. This can get quite cumbersome and repetitive. To make this easier toolkit has a special mode where it scans the source path for any `block.json` files and automatically adds any assets that are defined in there via the `script`, `editorScript`, `viewScript`, `style`, `editorStyle` keys with webpack. In order to handle `scriptModule` and `viewScriptModule` the `useScriptModules` mode needs to be enabled.

It also automatically moves all files including the `block.json` and PHP files to the `dist/blocks/` folder.

Expand All @@ -234,11 +234,41 @@ Since 10up-toolkit@6 this mode is on by default. To opt out of this mode you nee

By default, the source directory for blocks is `./includes/blocks/`. This can be customized via the `blocksDir` key in the paths' config.

### WordPress Script Module Handling

Since WordPress 6.5 ESM scripts are now officially supported. In fact, they are required in order to use some new features such as the Interactivity API. In WordPress these script modules need to coexist with commonJs scripts though. So it's not as easy as just switching the entire toolkit mode to output ESM instead of commonJS.

Since Toolkit 6.1 it is possible to enable `useScriptModules` in the toolkit config. This mode allows you to have both CommonJS and ESM scripts at the same time. Any existing entrypoints will continue to work as before. But a new `moduleEntry` key now allows for adding any additional ESM entrypoints to the toolkit config. Additionally any `scriptModule` & `viewScriptModule` files references inside `block.json` files will also get picked up and built as ESM scripts.

### WordPress Editor Styles

By default, 10up-toolkit will scope any css file named `editor-style.css` files with the
`.editor-styles-wrapper` class. Take a look at the default [postcss config](https://github.com/10up/10up-toolkit/blob/develop/packages/toolkit/config/postcss.config.js#L21) for more information.

## Handling of Global postCSS settings

With the introduction of block-specific stylesheets, we've started to break out our CSS from one bog monolithic `frontend.css` file into smaller individual files that only get loaded when the specific block is used on the page.

One downside to this approach however was that any postcss globals such as custom media queries, custom selectors, variables, and mixins defined in the main css file are not available to all the other block-specific stylesheets.

To fix this 10up-toolkit 6.1 introduces a new way to handle these global settings. There are now two special folders that toolkit watches for. `./assets/css/globals/` and `./assets/css/mixins/`. Any CSS files within these folders or nested within these folders get automatically loaded for all CSS files handled by Webpack. So if you define your custom breakpoints in a `./assets/css/globals/breakpoints.css` file that breakpoint will be available everywhere.

> [!WARNING]
> Please note that [PostCSS Global Data](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-global-data) does not add anything to the output of your CSS. It only injects data into PostCSS so that other plugins can actually use it.
If you need to customize the path of these global folders you can do so by modifying the `paths` in the tookit config.

```json
{
"10up-toolkit": {
"paths": {
"globalStylesDir": "./assets/css/globals/",
"globalMixinsDir": "./assets/css/mixins/"
}
}
}
```

## <a id="fast-refresh"></a>HMR and Fast Refresh

![react-fast-refresh-toolkit](https://user-images.githubusercontent.com/6104632/155181035-b77a53f8-6a45-454d-934c-5667bbb0f06a.gif)
Expand Down Expand Up @@ -568,6 +598,28 @@ config.plugins.push(
module.exports = config;
```

> [!NOTE]
> When `useScriptModules` mode is enabled the config returned from webpack here changes from an object to an array of two objects. The first one is the scripts config which matches the traditional structure. And the second object is the config for the ESM instance.
> ```js
> // webpack.config.js
> const config = require("10up-toolkit/config/webpack.config.js");
> const ProjectSpecificPlugin = require("project-specific-plugin");
>
> // We can now either add it to the first standard config
> config[0].plugins.push(
> // Append project specific plugin config.
> new ProjectSpecificPlugin()
> );
>
> // or to the second module specific config
> config[1].plugins.push(
> // Append project specific plugin config.
> new ProjectSpecificPlugin()
> );
>
> module.exports = config;
>```
### Customizing eslint and styling
To customize eslint, create a supported eslint config file at the root of your project. Make sure to extend the `@10up/eslint-config` package.
Expand Down Expand Up @@ -816,6 +868,11 @@ To override, use the `-f` or `--format` option
10up-toolkit build -f=commonjs
```

There also is a special mode for outputting both CommonJS and ESM assets at the same time. It can be enabled via the `useScriptModules` flag in the toolkit settings and enables you to define any module entrypoints via the `moduleEntry` key in the settings. At the same time enabling this flag also means that the `scriptModule` & `viewScriptModule` keys in `block.json` files automatically get built as modules.

> [!NOTE]
> Enabling has the side-effect that toolkit now needs to run two separate webpack instances. So the webpack config changes from an object to an array of objects. This is important to watch out for if you have a custom `webpack.config.js` file in your project and are customizing webpack yourself.
### Externals

This option is only useful in package mode and is used to override the webpack externals definitions. In package mode, the
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
html {
background: #f5f5f5;
padding: 20px;

@mixin margin-trim;

@media (--bp-small) {
padding: 40px;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Media Queries
*/
@custom-media --bp-tiny ( min-width: 25em ); /* 400px */
@custom-media --bp-small ( min-width: 30em ); /* 480px */
@custom-media --bp-medium ( min-width: 48em ); /* 768px */
@custom-media --bp-large ( min-width: 64em ); /* 1024px */
@custom-media --bp-xlarge ( min-width: 80em ); /* 1280px */
@custom-media --bp-xxlarge ( min-width: 90em ); /* 1440px */

/* WP Core Breakpoints (used for the admin bar for example) */
@custom-media --wp-small ( min-width: 600px );
@custom-media --wp-medium-max (max-width: 782px);
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
@define-mixin margin-trim {
margin-trim: block;

/* Fallback for browsers that don't support margin-trim */
@supports not (margin-trim: block) {

& > *:first-child {
margin-top: 0;
}

& > *:last-child {
margin-bottom: 0;
}
}
}
15 changes: 15 additions & 0 deletions packages/toolkit/__tests__/build-project-global-css/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"name": "test-build-project-global-css",
"10up-toolkit": {
"useBlockAssets": false,
"entry": {
"frontend-css": "./__fixtures__/assets/css/frontend/styles.css"
},
"paths": {
"srcDir": "./__fixtures__/assets/",
"cssLoaderPaths": ["./__fixtures__/assets/css", "./includes/blocks"],
"globalStylesDir": "./__fixtures__/assets/css/globals/",
"globalMixinsDir": "./__fixtures__/assets/css/mixins/"
}
}
}
24 changes: 24 additions & 0 deletions packages/toolkit/__tests__/build-project-global-css/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* eslint-disable import/no-extraneous-dependencies */
import spawn from 'cross-spawn';
import fs from 'fs';
import path from 'path';

describe('build a project', () => {
it('builds and compiles css with global css', async () => {
spawn.sync('node', ['../../scripts/build'], {
cwd: __dirname,
});

const frontendCss = path.join(__dirname, 'dist', 'css', 'frontend-css.css');

expect(fs.existsSync(frontendCss)).toBeTruthy();
expect(
fs.existsSync(path.join(__dirname, 'dist', 'css', 'frontend-css.asset.php')),
).toBeTruthy();

const compiledCSS = fs.readFileSync(frontendCss).toString();

// expect the compiled CSS to contain "min-width: 30em"
expect(compiledCSS).toMatch('min-width: 30em');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./dist
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.admin-class { color: blue; }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.test { color: red; }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import '../css/admin-styles.css';

export const admin = () => {};
12 changes: 12 additions & 0 deletions packages/toolkit/__tests__/build-project-modules/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "test-build-project",
"10up-toolkit": {
"useBlockAssets": false,
"entry": {
"frontend-css": "./__fixtures__/assets/css/frontend.css"
},
"moduleEntry": {
"admin": "./__fixtures__/assets/js/admin.js"
}
}
}
35 changes: 35 additions & 0 deletions packages/toolkit/__tests__/build-project-modules/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* eslint-disable import/no-extraneous-dependencies */
import spawn from 'cross-spawn';
import fs from 'fs';
import path from 'path';

describe('build a project with moduleEntry', () => {
it('builds and compiles js and css', async () => {
spawn.sync('node', ['../../scripts/build', '--block-modules'], {
cwd: __dirname,
});

const adminJsPath = path.join(__dirname, 'dist', 'js', 'admin.js');

expect(fs.existsSync(adminJsPath)).toBeTruthy();
expect(fs.existsSync(path.join(__dirname, 'dist', 'css', 'frontend-css.css'))).toBeTruthy();
expect(
fs.existsSync(path.join(__dirname, 'dist', 'css', 'frontend-css.asset.php')),
).toBeTruthy();

// ensure admin is a module
const adminJs = fs.readFileSync(adminJsPath).toString();
expect(adminJs).toMatch(/export {.*};/);
});

it('extracts css imported in js files', () => {
spawn.sync('node', ['../../scripts/build', '--block-modules'], {
cwd: __dirname,
});
// chunk name for css imported in js matches the js entry point
expect(fs.existsSync(path.join(__dirname, 'dist', 'css', 'admin.css'))).toBeTruthy();

// this should not exist since it is not an entry point on its own
expect(fs.existsSync(path.join(__dirname, 'dist', 'css', 'admin-styles.css'))).toBeFalsy();
});
});
Loading

0 comments on commit 1c01f08

Please sign in to comment.