diff --git a/.changeset/early-kiwis-arrive.md b/.changeset/early-kiwis-arrive.md deleted file mode 100644 index 4b34766c..00000000 --- a/.changeset/early-kiwis-arrive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"10up-toolkit": minor ---- - -Add support for `scriptModule` & `viewScriptModule` assets diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index e10cfdd5..00000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "mode": "pre", - "tag": "next", - "initialVersions": { - "@10up/babel-preset-default": "2.1.1", - "@10up/eslint-config": "4.0.0", - "@10up/stylelint-config": "3.0.0", - "10up-toolkit": "6.0.1", - "tenup-theme": "1.1.5-next.7", - "@10up/component-accordion": "2.1.5", - "@10up/library-ts-test": "2.1.5" - }, - "changesets": [ - "early-kiwis-arrive" - ] -} diff --git a/package-lock.json b/package-lock.json index cddbc405..4991d755 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2325,6 +2325,27 @@ "postcss": "^8.4" } }, + "node_modules/@csstools/postcss-global-data": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@csstools/postcss-global-data/-/postcss-global-data-2.1.1.tgz", + "integrity": "sha512-tihdBLogY2G5jgUSu2jKSEVeOcnWqsz6k7UmPM7+ezhuV9FP5MIyX35Hc/YvqipQLRNsfBj9wRkBvsE7k1GM8A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, "node_modules/@csstools/postcss-gradients-interpolation-method": { "version": "4.0.9", "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-4.0.9.tgz", @@ -26806,10 +26827,11 @@ }, "packages/toolkit": { "name": "10up-toolkit", - "version": "6.0.0", + "version": "6.1.0", "license": "GPL-2.0-or-later", "dependencies": { "@babel/eslint-parser": "^7.23.3", + "@csstools/postcss-global-data": "^2.1.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@svgr/webpack": "^8.1.0", "@typescript-eslint/eslint-plugin": "^6.17.0", @@ -26862,9 +26884,9 @@ "10up-toolkit": "bin/10up-toolkit.js" }, "devDependencies": { - "@10up/babel-preset-default": "^2.1.1", - "@10up/eslint-config": "^4.0.0", - "@10up/stylelint-config": "^3.0.0" + "@10up/babel-preset-default": ">=2.1.1", + "@10up/eslint-config": ">=4.0.0", + "@10up/stylelint-config": ">=3.0.0" }, "engines": { "node": ">=16", @@ -28275,7 +28297,7 @@ "@linaria/babel-preset": "^5.0.3", "@linaria/webpack-loader": "^5.0.3", "@wordpress/env": "^5.0.0", - "10up-toolkit": "^6.0.0" + "10up-toolkit": "^6.1.0" }, "engines": { "node": ">=12.0.0" @@ -28292,7 +28314,7 @@ "@testing-library/dom": "9.3.3", "@testing-library/jest-dom": "^6.2.0", "@testing-library/user-event": "^14.5.2", - "10up-toolkit": "^6.0.0", + "10up-toolkit": "^6.1.0", "jest-axe": "^8.0.0", "jest-environment-jsdom": "~29.7.0" } @@ -28305,7 +28327,7 @@ "xss": "^1.0.11" }, "devDependencies": { - "10up-toolkit": "^6.0.0" + "10up-toolkit": "^6.1.0" } }, "projects/library/node_modules/@jest/console": { diff --git a/packages/toolkit/CHANGELOG.md b/packages/toolkit/CHANGELOG.md index 33a41835..93079cbb 100644 --- a/packages/toolkit/CHANGELOG.md +++ b/packages/toolkit/CHANGELOG.md @@ -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 diff --git a/packages/toolkit/README.md b/packages/toolkit/README.md index 8d66c234..54b566e1 100644 --- a/packages/toolkit/README.md +++ b/packages/toolkit/README.md @@ -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. @@ -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/" + } + } +} +``` + ## HMR and Fast Refresh ![react-fast-refresh-toolkit](https://user-images.githubusercontent.com/6104632/155181035-b77a53f8-6a45-454d-934c-5667bbb0f06a.gif) @@ -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. @@ -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 diff --git a/packages/toolkit/__tests__/build-project-global-css/.gitignore b/packages/toolkit/__tests__/build-project-global-css/.gitignore new file mode 100644 index 00000000..0fa2fd4f --- /dev/null +++ b/packages/toolkit/__tests__/build-project-global-css/.gitignore @@ -0,0 +1 @@ +./dist diff --git a/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/frontend/styles.css b/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/frontend/styles.css new file mode 100644 index 00000000..0ee24254 --- /dev/null +++ b/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/frontend/styles.css @@ -0,0 +1,10 @@ +html { + background: #f5f5f5; + padding: 20px; + + @mixin margin-trim; + + @media (--bp-small) { + padding: 40px; + } +} diff --git a/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/globals/media-queries.css b/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/globals/media-queries.css new file mode 100644 index 00000000..27f4c715 --- /dev/null +++ b/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/globals/media-queries.css @@ -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); diff --git a/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/mixins/margin-trim.css b/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/mixins/margin-trim.css new file mode 100644 index 00000000..f0ad06d5 --- /dev/null +++ b/packages/toolkit/__tests__/build-project-global-css/__fixtures__/assets/css/mixins/margin-trim.css @@ -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; + } + } +} diff --git a/packages/toolkit/__tests__/build-project-global-css/package.json b/packages/toolkit/__tests__/build-project-global-css/package.json new file mode 100644 index 00000000..e3bb8271 --- /dev/null +++ b/packages/toolkit/__tests__/build-project-global-css/package.json @@ -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/" + } + } +} diff --git a/packages/toolkit/__tests__/build-project-global-css/test.js b/packages/toolkit/__tests__/build-project-global-css/test.js new file mode 100644 index 00000000..02bdea0e --- /dev/null +++ b/packages/toolkit/__tests__/build-project-global-css/test.js @@ -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'); + }); +}); diff --git a/packages/toolkit/__tests__/build-project-modules/.gitignore b/packages/toolkit/__tests__/build-project-modules/.gitignore new file mode 100644 index 00000000..0fa2fd4f --- /dev/null +++ b/packages/toolkit/__tests__/build-project-modules/.gitignore @@ -0,0 +1 @@ +./dist diff --git a/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/css/admin-styles.css b/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/css/admin-styles.css new file mode 100644 index 00000000..46b115dc --- /dev/null +++ b/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/css/admin-styles.css @@ -0,0 +1 @@ +.admin-class { color: blue; } diff --git a/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/css/frontend.css b/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/css/frontend.css new file mode 100644 index 00000000..635ea838 --- /dev/null +++ b/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/css/frontend.css @@ -0,0 +1 @@ +.test { color: red; } diff --git a/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/js/admin.js b/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/js/admin.js new file mode 100644 index 00000000..015d49eb --- /dev/null +++ b/packages/toolkit/__tests__/build-project-modules/__fixtures__/assets/js/admin.js @@ -0,0 +1,3 @@ +import '../css/admin-styles.css'; + +export const admin = () => {}; diff --git a/packages/toolkit/__tests__/build-project-modules/package.json b/packages/toolkit/__tests__/build-project-modules/package.json new file mode 100644 index 00000000..93a232e1 --- /dev/null +++ b/packages/toolkit/__tests__/build-project-modules/package.json @@ -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" + } + } +} diff --git a/packages/toolkit/__tests__/build-project-modules/test.js b/packages/toolkit/__tests__/build-project-modules/test.js new file mode 100644 index 00000000..88d188c8 --- /dev/null +++ b/packages/toolkit/__tests__/build-project-modules/test.js @@ -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(); + }); +}); diff --git a/packages/toolkit/config/__tests__/__snapshots__/postscss.config.js.snap b/packages/toolkit/config/__tests__/__snapshots__/postscss.config.js.snap index a502127d..86295d84 100644 --- a/packages/toolkit/config/__tests__/__snapshots__/postscss.config.js.snap +++ b/packages/toolkit/config/__tests__/__snapshots__/postscss.config.js.snap @@ -252,9 +252,14 @@ a c, b c, a d, b d { exports[`postcss.config.js build a proper postcss config file for non-editor styles: env=development 1`] = ` { "plugins": { + "@csstools/postcss-global-data": { + "files": [], + }, "cssnano": false, "postcss-import": {}, - "postcss-mixins": {}, + "postcss-mixins": { + "mixinsFiles": [], + }, "postcss-preset-env": { "features": { "custom-properties": false, @@ -268,6 +273,9 @@ exports[`postcss.config.js build a proper postcss config file for non-editor sty exports[`postcss.config.js build a proper postcss config file for non-editor styles: env=production 1`] = ` { "plugins": { + "@csstools/postcss-global-data": { + "files": [], + }, "cssnano": { "preset": [ "default", @@ -286,7 +294,9 @@ exports[`postcss.config.js build a proper postcss config file for non-editor sty ], }, "postcss-import": {}, - "postcss-mixins": {}, + "postcss-mixins": { + "mixinsFiles": [], + }, "postcss-preset-env": { "features": { "custom-properties": false, @@ -300,6 +310,9 @@ exports[`postcss.config.js build a proper postcss config file for non-editor sty exports[`postcss.config.js builds a proper postcss config file for editor styles: env=development 1`] = ` { "plugins": { + "@csstools/postcss-global-data": { + "files": [], + }, "cssnano": false, "postcss-editor-styles-wrapper": { "ignore": [ @@ -324,7 +337,9 @@ exports[`postcss.config.js builds a proper postcss config file for editor styles ], }, "postcss-import": {}, - "postcss-mixins": {}, + "postcss-mixins": { + "mixinsFiles": [], + }, "postcss-preset-env": { "features": { "custom-properties": false, @@ -338,6 +353,9 @@ exports[`postcss.config.js builds a proper postcss config file for editor styles exports[`postcss.config.js builds a proper postcss config file for editor styles: env=production 1`] = ` { "plugins": { + "@csstools/postcss-global-data": { + "files": [], + }, "cssnano": { "preset": [ "default", @@ -378,7 +396,9 @@ exports[`postcss.config.js builds a proper postcss config file for editor styles ], }, "postcss-import": {}, - "postcss-mixins": {}, + "postcss-mixins": { + "mixinsFiles": [], + }, "postcss-preset-env": { "features": { "custom-properties": false, diff --git a/packages/toolkit/config/__tests__/__snapshots__/webpack-cli-arguments.js.snap b/packages/toolkit/config/__tests__/__snapshots__/webpack-cli-arguments.js.snap index b1260312..f74a52f9 100644 --- a/packages/toolkit/config/__tests__/__snapshots__/webpack-cli-arguments.js.snap +++ b/packages/toolkit/config/__tests__/__snapshots__/webpack-cli-arguments.js.snap @@ -1208,7 +1208,10 @@ exports[`webpack.config.js builds modules 1`] = ` "output": { "chunkFormat": "module", "clean": false, - "filename": "blocks/[name].js", + "filename": "pathData => { + const isBlockAsset = moduleBuildFiles[pathData.chunk.name].match(/\\/blocks?\\//) || moduleBuildFiles[pathData.chunk.name].match(/\\\\blocks?\\\\/); + return isBlockAsset ? projectConfig.filenames.block : projectConfig.filenames.js; + }", "library": { "type": "module", }, diff --git a/packages/toolkit/config/paths.config.js b/packages/toolkit/config/paths.config.js index 21879748..8613dc79 100644 --- a/packages/toolkit/config/paths.config.js +++ b/packages/toolkit/config/paths.config.js @@ -3,5 +3,7 @@ module.exports = { blocksStyles: './assets/css/blocks/', copyAssetsDir: './assets/', cssLoaderPaths: ['./assets/css', './includes/blocks'], + globalMixinsDir: './assets/css/mixins/', + globalStylesDir: './assets/css/globals/', srcDir: './assets/', }; diff --git a/packages/toolkit/config/postcss.config.js b/packages/toolkit/config/postcss.config.js index 73d2b3dd..57f1efbf 100644 --- a/packages/toolkit/config/postcss.config.js +++ b/packages/toolkit/config/postcss.config.js @@ -1,10 +1,24 @@ const path = require('path'); +const glob = require('fast-glob'); + +const { getTenUpScriptsConfig } = require('../utils'); module.exports = ({ file, env }) => { + const projectConfig = getTenUpScriptsConfig(); + const { globalStylesDir, globalMixinsDir } = projectConfig.paths; + + const globalCssFiles = glob.sync(`${globalStylesDir}**/*.css`); + const globalMixinFiles = glob.sync(`${globalMixinsDir}**/*.css`); + const config = { plugins: { 'postcss-import': {}, - 'postcss-mixins': {}, + '@csstools/postcss-global-data': { + files: globalCssFiles, + }, + 'postcss-mixins': { + mixinsFiles: globalMixinFiles, + }, 'postcss-preset-env': { stage: 0, features: { diff --git a/packages/toolkit/config/webpack.config.js b/packages/toolkit/config/webpack.config.js index 7137a2e5..ffb66ee5 100644 --- a/packages/toolkit/config/webpack.config.js +++ b/packages/toolkit/config/webpack.config.js @@ -6,6 +6,7 @@ const { getTenUpScriptsConfig, getTenUpScriptsPackageBuildConfig, } = require('../utils'); +const { getModuleBuildFiles } = require('../utils/config'); const { getEntryPoints, @@ -25,12 +26,13 @@ const projectConfig = getTenUpScriptsConfig(); const packageConfig = getTenUpScriptsPackageBuildConfig(); const { source, main } = packageConfig; const buildFiles = getBuildFiles(); +const moduleBuildFiles = getModuleBuildFiles(); // assume it's a package if there's source and main const isPackage = typeof source !== 'undefined' && typeof main !== 'undefined'; const isProduction = process.env.NODE_ENV === 'production'; const mode = isProduction ? 'production' : 'development'; -const useBlockModules = projectConfig.useBlockModules || false; +const useScriptModules = projectConfig.useScriptModules || false; const defaultTargets = [ '> 1%', @@ -44,6 +46,7 @@ const config = { projectConfig, packageConfig, buildFiles, + moduleBuildFiles, isPackage, mode, isProduction, @@ -95,8 +98,13 @@ const moduleConfig = { ...baseConfig.output.library, type: 'module', }, - filename: 'blocks/[name].js', + filename: (pathData) => { + const isBlockAsset = + moduleBuildFiles[pathData.chunk.name].match(/\/blocks?\//) || + moduleBuildFiles[pathData.chunk.name].match(/\\blocks?\\/); + return isBlockAsset ? projectConfig.filenames.block : projectConfig.filenames.js; + }, }, }; -module.exports = useBlockModules ? [scriptsConfig, moduleConfig] : scriptsConfig; +module.exports = useScriptModules ? [scriptsConfig, moduleConfig] : scriptsConfig; diff --git a/packages/toolkit/config/webpack/entry.js b/packages/toolkit/config/webpack/entry.js index dd2ffbca..efc0a347 100644 --- a/packages/toolkit/config/webpack/entry.js +++ b/packages/toolkit/config/webpack/entry.js @@ -12,6 +12,7 @@ module.exports = ({ projectConfig: { devServer, paths, useBlockAssets, filenames, loadBlockSpecificStyles }, packageConfig: { packageType, source, main, umd, libraryName }, buildFiles, + moduleBuildFiles, }) => { let additionalEntrypoints = {}; @@ -131,7 +132,8 @@ module.exports = ({ } if (buildType === 'module') { - return additionalEntrypoints; + Object.assign(moduleBuildFiles, additionalEntrypoints); + return moduleBuildFiles; } // merge the new entrypoints with the existing ones diff --git a/packages/toolkit/config/webpack/output.js b/packages/toolkit/config/webpack/output.js index 74fbf2e1..60a51f9a 100644 --- a/packages/toolkit/config/webpack/output.js +++ b/packages/toolkit/config/webpack/output.js @@ -3,7 +3,7 @@ const path = require('path'); module.exports = ({ isPackage, packageConfig: { packageType, main }, - projectConfig: { filenames, useBlockModules, hot, publicPath }, + projectConfig: { filenames, useScriptModules, hot, publicPath }, buildFiles, }) => { if (isPackage) { @@ -23,7 +23,7 @@ module.exports = ({ return { // when in block module mode or when hot reloading is active we should not clear dist folder between builds - clean: !useBlockModules && !hot, + clean: !useScriptModules && !hot, path: path.resolve(process.cwd(), 'dist'), chunkFilename: filenames.jsChunk, publicPath, diff --git a/packages/toolkit/package.json b/packages/toolkit/package.json index 94825a48..f10528be 100644 --- a/packages/toolkit/package.json +++ b/packages/toolkit/package.json @@ -13,27 +13,30 @@ "url": "git+https://github.com/10up/10up-toolkit.git", "directory": "packages/toolkit" }, - "version": "6.1.0-next.0", + "version": "6.1.0", "bin": { "10up-toolkit": "bin/10up-toolkit.js" }, "dependencies": { "@babel/eslint-parser": "^7.23.3", + "@csstools/postcss-global-data": "^2.1.1", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.11", "@svgr/webpack": "^8.1.0", "@typescript-eslint/eslint-plugin": "^6.17.0", "@typescript-eslint/parser": "^6.17.0", "@wordpress/dependency-extraction-webpack-plugin": "^5.4.0", - "@wordpress/jest-console": "^7.19.0", "@wordpress/eslint-plugin": "^17.5.0", + "@wordpress/jest-console": "^7.19.0", "babel-jest": "^29.7.0", "babel-loader": "^9.1.3", "camelcase": "^6.3.0", "copy-webpack-plugin": "^11.0.0", "core-js": "^3.35.0", + "core-js-pure": "^3.35.0", "cross-spawn": "^7.0.3", "css-loader": "^6.8.1", "cssnano": "^6.0.3", + "error-stack-parser": "^2.1.4", "eslint-webpack-plugin": "^4.0.1", "fast-glob": "^3.3.2", "html-webpack-plugin": "^5.6.0", @@ -63,9 +66,7 @@ "webpack-bundle-analyzer": "^4.10.1", "webpack-dev-server": "^4.15.1", "webpack-sources": "^3.2.3", - "webpackbar": "^6.0.0", - "error-stack-parser": "^2.1.4", - "core-js-pure": "^3.35.0" + "webpackbar": "^6.0.0" }, "devDependencies": { "@10up/babel-preset-default": ">=2.1.1", @@ -73,12 +74,12 @@ "@10up/stylelint-config": ">=3.0.0" }, "peerDependencies": { - "typescript": ">=5.0.0", "@10up/babel-preset-default": "^2.1.1", "@10up/eslint-config": "^4.0.0", "@10up/stylelint-config": "^3.0.0", + "@linaria/babel-preset": ">=4.3.3", "@linaria/webpack-loader": ">=4.1.11", - "@linaria/babel-preset": ">=4.3.3" + "typescript": ">=5.0.0" }, "peerDependenciesMeta": { "@linaria/webpack-loader": { diff --git a/packages/toolkit/utils/config.js b/packages/toolkit/utils/config.js index c9cebb46..08275b57 100644 --- a/packages/toolkit/utils/config.js +++ b/packages/toolkit/utils/config.js @@ -109,7 +109,7 @@ const getDefaultConfig = () => { const analyze = hasArgInCLI('--analyze'); const include = hasArgInCLI('--include') ? getArgFromCLI('--include').split(',') : []; const sourcemap = hasArgInCLI('--sourcemap'); - const useBlockModules = hasArgInCLI('--block-modules') || false; + const useScriptModules = hasArgInCLI('--block-modules') || false; const buildFilesPath = hasProjectFile('buildfiles.config.js') ? fromProjectRoot('buildfiles.config.js') @@ -124,6 +124,7 @@ const getDefaultConfig = () => { return { entry: require(buildFilesPath), + moduleEntry: {}, filenames: require(filenamesPath), paths: require(pathsPath), wordpress: wpMode !== 'false', @@ -138,9 +139,9 @@ const getDefaultConfig = () => { typeof process.env.TENUP_NO_EXTERNALS === 'undefined' || !process.env.TENUP_NO_EXTERNALS, publicPath: process.env.ASSET_PATH || undefined, - useBlockAssets: true, loadBlockSpecificStyles: false, - useBlockModules, + useBlockAssets: true, + useScriptModules, include, }; }; @@ -296,6 +297,22 @@ const getBuildFiles = () => { return entries; }; +const getModuleBuildFiles = () => { + const { moduleEntry } = getTenUpScriptsConfig(); + + const entries = {}; + + Object.keys(moduleEntry).forEach((key) => { + const filePath = path.resolve(process.cwd(), moduleEntry[key]); + + if (fileExists(filePath)) { + entries[key] = filePath; + } + }); + + return entries; +}; + module.exports = { hasBabelConfig, getJestOverrideConfigFile, @@ -304,6 +321,7 @@ module.exports = { hasPostCSSConfig, hasStylelintConfig, getBuildFiles, + getModuleBuildFiles, hasEslintignoreConfig, hasEslintConfig, getTenUpScriptsConfig, diff --git a/projects/10up-theme/assets/css/frontend/global/index.css b/projects/10up-theme/assets/css/frontend/global/index.css old mode 100755 new mode 100644 index 9e5b3614..7b6694be --- a/projects/10up-theme/assets/css/frontend/global/index.css +++ b/projects/10up-theme/assets/css/frontend/global/index.css @@ -1,2 +1 @@ @import url("colors.css"); -@import url("media-queries.css"); diff --git a/projects/10up-theme/assets/css/frontend/style.css b/projects/10up-theme/assets/css/frontend/style.css index 779be8e2..e20898cb 100755 --- a/projects/10up-theme/assets/css/frontend/style.css +++ b/projects/10up-theme/assets/css/frontend/style.css @@ -16,6 +16,12 @@ html { background: #f5f5f5; padding: 20px; + + @mixin margin-trim; + + @media (--bp-small) { + padding: 40px; + } } p { diff --git a/projects/10up-theme/assets/css/frontend/global/media-queries.css b/projects/10up-theme/assets/css/globals/media-queries.css similarity index 100% rename from projects/10up-theme/assets/css/frontend/global/media-queries.css rename to projects/10up-theme/assets/css/globals/media-queries.css diff --git a/projects/10up-theme/assets/css/mixins/margin-trim.css b/projects/10up-theme/assets/css/mixins/margin-trim.css new file mode 100644 index 00000000..60de9334 --- /dev/null +++ b/projects/10up-theme/assets/css/mixins/margin-trim.css @@ -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; + } + } +} diff --git a/projects/10up-theme/assets/js/frontend/frontend-module.js b/projects/10up-theme/assets/js/frontend/frontend-module.js new file mode 100644 index 00000000..c606cecc --- /dev/null +++ b/projects/10up-theme/assets/js/frontend/frontend-module.js @@ -0,0 +1,12 @@ +import { store } from '@wordpress/interactivity'; + +const { state } = store('frontend', { + state: { + isExpanded: false, + }, + actions: { + toggleExpanded() { + state.isExpanded = !state.isExpanded; + }, + }, +}); diff --git a/projects/10up-theme/includes/blocks/example/style.css b/projects/10up-theme/includes/blocks/example/style.css index 2a77f355..7710021d 100644 --- a/projects/10up-theme/includes/blocks/example/style.css +++ b/projects/10up-theme/includes/blocks/example/style.css @@ -6,4 +6,10 @@ .wp-block-example-block__title { border: 3px dashed #ccc; padding: 1em; + + @mixin margin-trim; + + @media (--bp-small) { + padding: 2em; + } } diff --git a/projects/10up-theme/package.json b/projects/10up-theme/package.json index 22513459..8bb435f8 100644 --- a/projects/10up-theme/package.json +++ b/projects/10up-theme/package.json @@ -20,7 +20,7 @@ "@linaria/babel-preset": "^5.0.3", "@linaria/webpack-loader": "^5.0.3", "@wordpress/env": "^5.0.0", - "10up-toolkit": "^6.1.0-next.0" + "10up-toolkit": "^6.1.0" }, "dependencies": { "@10up/block-components": "^1.18.0", @@ -34,7 +34,7 @@ }, "10up-toolkit": { "useBlockAssets": true, - "useBlockModules": true, + "useScriptModules": true, "entry": { "admin": "./assets/js/admin/admin.js", "frontend": "./assets/js/frontend/frontend.js", @@ -46,6 +46,9 @@ "styleguide-style": "./assets/css/styleguide/styleguide.css", "core-block-overrides": "./includes/core-block-overrides.js", "test-style": "./assets/css/frontend/testing.scss" + }, + "moduleEntry": { + "frontend-module": "./assets/js/frontend/frontend-module.js" } } } diff --git a/projects/library-ts/package.json b/projects/library-ts/package.json index c840b529..7a3205f1 100644 --- a/projects/library-ts/package.json +++ b/projects/library-ts/package.json @@ -39,7 +39,7 @@ }, "homepage": "https://github.com/10up/component-accordion#readme", "devDependencies": { - "10up-toolkit": "^6.1.0-next.0" + "10up-toolkit": "^6.1.0" }, "dependencies": { "xss": "^1.0.11" diff --git a/projects/library/package.json b/projects/library/package.json index 5de96bf7..c4bd8f89 100644 --- a/projects/library/package.json +++ b/projects/library/package.json @@ -26,7 +26,7 @@ }, "homepage": "https://github.com/10up/component-accordion#readme", "devDependencies": { - "10up-toolkit": "^6.1.0-next.0", + "10up-toolkit": "^6.1.0", "@testing-library/dom": "9.3.3", "@testing-library/jest-dom": "^6.2.0", "@testing-library/user-event": "^14.5.2",