From 1cb7693d191d7e498167899d1419ea78eb6a30d6 Mon Sep 17 00:00:00 2001 From: Ryan Christian <33403762+rschristian@users.noreply.github.com> Date: Sun, 24 Jul 2022 19:50:20 -0500 Subject: [PATCH] refactor: Determine CSS module by filename, not directory (#1714) * refactor: Determine CSS module by filename, not directory * docs: Adding changeset * refactor: Project creation pull from templates 'main' branch * test: Updating tests * revert: Accidentally removed log message --- .changeset/cyan-tomatoes-count.md | 11 ++++ packages/cli/global.d.ts | 13 +++++ packages/cli/src/commands/create.js | 5 ++ packages/cli/src/lib/webpack/run-webpack.js | 2 +- .../src/lib/webpack/webpack-base-config.js | 41 +++++++-------- packages/cli/tests/build.test.js | 23 ++++----- packages/cli/tests/images/build.js | 50 ++++++++----------- packages/cli/tests/images/create.js | 6 +-- .../css-auto-modules/components/index.js | 4 -- .../css-auto-modules/components/style.css | 3 -- .../subjects/css-auto-modules/routes/index.js | 4 -- .../css-auto-modules/routes/style.css | 3 -- .../index.js | 9 ++-- .../package.json | 0 .../global.css => css-modules/style.css} | 0 .../subjects/css-modules/style.module.css | 3 ++ .../subjects/css-sass/components/app/index.js | 11 ---- .../css-sass/components/app/style.scss | 3 -- packages/cli/tests/subjects/css-sass/index.js | 17 ++++++- .../tests/subjects/css-sass/style.module.sass | 2 + .../tests/subjects/css-sass/style.module.scss | 3 ++ .../cli/tests/subjects/css-sass/style.sass | 2 + .../cli/tests/subjects/css-sass/style.scss | 3 ++ 23 files changed, 115 insertions(+), 103 deletions(-) create mode 100644 .changeset/cyan-tomatoes-count.md delete mode 100644 packages/cli/tests/subjects/css-auto-modules/components/index.js delete mode 100644 packages/cli/tests/subjects/css-auto-modules/components/style.css delete mode 100644 packages/cli/tests/subjects/css-auto-modules/routes/index.js delete mode 100644 packages/cli/tests/subjects/css-auto-modules/routes/style.css rename packages/cli/tests/subjects/{css-auto-modules => css-modules}/index.js (52%) rename packages/cli/tests/subjects/{css-auto-modules => css-modules}/package.json (100%) rename packages/cli/tests/subjects/{css-auto-modules/global.css => css-modules/style.css} (100%) create mode 100644 packages/cli/tests/subjects/css-modules/style.module.css delete mode 100644 packages/cli/tests/subjects/css-sass/components/app/index.js delete mode 100644 packages/cli/tests/subjects/css-sass/components/app/style.scss create mode 100644 packages/cli/tests/subjects/css-sass/style.module.sass create mode 100644 packages/cli/tests/subjects/css-sass/style.module.scss create mode 100644 packages/cli/tests/subjects/css-sass/style.sass create mode 100644 packages/cli/tests/subjects/css-sass/style.scss diff --git a/.changeset/cyan-tomatoes-count.md b/.changeset/cyan-tomatoes-count.md new file mode 100644 index 000000000..5a82bcac3 --- /dev/null +++ b/.changeset/cyan-tomatoes-count.md @@ -0,0 +1,11 @@ +--- +'preact-cli': major +--- + +Alters CSS Module detection to instead rely upon file names, rather than directory names. + +Treating all CSS files found within `routes/` and `components/` as CSS Modules was not obvious, nor did it offer an easy way to opt out (or in) without editing the Webpack config itself. + +This change makes is so that users can opt into CSS Modules from anywhere in their app by instead naming their CSS files according to the pattern `*.module.css`. + +Anyone using CSS Modules within `routes/` or `components/` will need to alter their CSS files to be `x.module.css`. If you've disabled CSS Modules in your `preact.config.js`, you can remove that bit of configuration and use file names to instead determine behavior. diff --git a/packages/cli/global.d.ts b/packages/cli/global.d.ts index babb3438b..d45a4fcaf 100644 --- a/packages/cli/global.d.ts +++ b/packages/cli/global.d.ts @@ -15,3 +15,16 @@ declare module 'shelljs' { }; export = shell; } + +declare module '*.module.css' { + const classes: { [key: string]: string }; + export default classes; +} +declare module '*.module.sass' { + const classes: { [key: string]: string }; + export default classes; +} +declare module '*.module.scss' { + const classes: { [key: string]: string }; + export default classes; +} diff --git a/packages/cli/src/commands/create.js b/packages/cli/src/commands/create.js index eccb6e6f3..159c1faa1 100644 --- a/packages/cli/src/commands/create.js +++ b/packages/cli/src/commands/create.js @@ -220,6 +220,11 @@ exports.create = async function createCommand(repo, dest, argv) { if (!repo.includes('/')) { repo = `${ORG}/${repo}`; info(`Assuming you meant ${repo}...`); + + // TODO: Remove this after updating all templates + if (repo.endsWith('default') || repo.endsWith('typescript')) { + repo += '#next'; + } } if (!existsSync(resolve(cwd, dest, 'src'))) { diff --git a/packages/cli/src/lib/webpack/run-webpack.js b/packages/cli/src/lib/webpack/run-webpack.js index 037461a1a..53bd3abdc 100644 --- a/packages/cli/src/lib/webpack/run-webpack.js +++ b/packages/cli/src/lib/webpack/run-webpack.js @@ -143,7 +143,7 @@ function writeJsonStats(cwd, stats) { function allFields(stats, field, fields = [], name = null) { const info = stats.toJson({ errors: true, - warnings: false, + warnings: true, errorDetails: false, }); const addCompilerPrefix = msg => diff --git a/packages/cli/src/lib/webpack/webpack-base-config.js b/packages/cli/src/lib/webpack/webpack-base-config.js index 45b169d13..4875aa86e 100644 --- a/packages/cli/src/lib/webpack/webpack-base-config.js +++ b/packages/cli/src/lib/webpack/webpack-base-config.js @@ -50,7 +50,7 @@ function resolveTsconfig(cwd, isProd) { * @returns {import('webpack').Configuration} */ module.exports = function createBaseConfig(env) { - const { cwd, isProd, isWatch, src, source } = env; + const { cwd, isProd, src, source } = env; const IS_SOURCE_PREACT_X_OR_ABOVE = isInstalledVersionPreactXOrAbove(cwd); // Apply base-level `env` values env.dest = resolve(cwd, env.dest || 'build'); @@ -216,20 +216,15 @@ module.exports = function createBaseConfig(env) { ], }, { - // User styles test: /\.(p?css|less|s[ac]ss|styl)$/, - include: [source('components'), source('routes')], + exclude: /\.module\.(p?css|less|s[ac]ss|styl)$/, use: [ - isWatch - ? require.resolve('style-loader') - : MiniCssExtractPlugin.loader, + isProd + ? MiniCssExtractPlugin.loader + : require.resolve('style-loader'), { loader: require.resolve('css-loader'), options: { - modules: { - localIdentName: '[local]__[hash:base64:5]', - }, - importLoaders: 1, sourceMap: true, }, }, @@ -243,18 +238,25 @@ module.exports = function createBaseConfig(env) { }, }, ], + // Don't consider CSS imports dead code even if the + // containing package claims to have no side effects. + // Remove this when webpack adds a warning or an error for this. + // See https://github.com/webpack/webpack/issues/6571 + sideEffects: true, }, { - // External / `node_module` styles - test: /\.(p?css|less|s[ac]ss|styl)$/, - exclude: [source('components'), source('routes')], + test: /\.module\.(p?css|less|s[ac]ss|styl)$/, use: [ - isWatch - ? require.resolve('style-loader') - : MiniCssExtractPlugin.loader, + isProd + ? MiniCssExtractPlugin.loader + : require.resolve('style-loader'), { loader: require.resolve('css-loader'), options: { + modules: { + localIdentName: '[local]__[hash:base64:5]', + }, + importLoaders: 1, sourceMap: true, }, }, @@ -268,11 +270,6 @@ module.exports = function createBaseConfig(env) { }, }, ], - // Don't consider CSS imports dead code even if the - // containing package claims to have no side effects. - // Remove this when webpack adds a warning or an error for this. - // See https://github.com/webpack/webpack/issues/6571 - sideEffects: true, }, { test: /\.(xml|html|txt|md)$/, @@ -362,7 +359,7 @@ module.exports = function createBaseConfig(env) { mode: isProd ? 'production' : 'development', - devtool: isWatch ? 'eval-cheap-module-source-map' : 'source-map', + devtool: isProd ? 'source-map' : 'eval-cheap-module-source-map', node: { __filename: false, diff --git a/packages/cli/tests/build.test.js b/packages/cli/tests/build.test.js index 650e18421..316de7e35 100644 --- a/packages/cli/tests/build.test.js +++ b/packages/cli/tests/build.test.js @@ -177,7 +177,9 @@ describe('preact build', () => { await rename(join(dir, 'index.js'), join(dir, 'renamed-src/index.js')); await rename(join(dir, 'style.css'), join(dir, 'renamed-src/style.css')); - await expect(buildFast(dir, { src: 'renamed-src' })).resolves.not.toThrow(); + await expect( + buildFast(dir, { src: 'renamed-src' }) + ).resolves.not.toThrow(); }); it('--dest', async () => { @@ -361,18 +363,13 @@ describe('preact build', () => { expect(builtStylesheet).toMatch('h2{color:green}'); }); - it('should use CSS Modules in `routes` and `components` directories', async () => { - let dir = await subject('css-auto-modules'); + it('should use plain CSS & CSS Modules together, determining loading method by filename', async () => { + let dir = await subject('css-modules'); await buildFast(dir); const builtStylesheet = await getOutputFile(dir, /bundle\.\w{5}\.css$/); - const builtSplitStylesheet = await getOutputFile( - dir, - /route-index\.chunk\.\w{5}\.css$/ - ); expect(builtStylesheet).toMatch('h1{color:red}'); - expect(builtStylesheet).toMatch(/\.text__\w{5}{color:tan}/); - expect(builtSplitStylesheet).toMatch(/\.text__\w{5}{color:red}/); + expect(builtStylesheet).toMatch(/\.text__\w{5}{color:blue}/); }); it('should inline critical CSS only', async () => { @@ -394,12 +391,14 @@ describe('preact build', () => { expect(builtStylesheet).toMatch('h1{background:#673ab8}'); }); - it('should use SASS styles', async () => { + it('should use SASS, SCSS, and CSS Modules for each', async () => { let dir = await subject('css-sass'); await buildFast(dir); + const builtStylesheet = await getOutputFile(dir, /bundle\.\w{5}\.css$/); - let body = await getBody(dir); - looksLike(body, images.sass); + expect(builtStylesheet).toMatch('h1{background:blue;color:red}'); + expect(builtStylesheet).toMatch(/\.text__\w{5}{color:blue}/); + expect(builtStylesheet).toMatch(/\.text__\w{5}{background:red}/); }); }); diff --git a/packages/cli/tests/images/build.js b/packages/cli/tests/images/build.js index 0792cc037..011482e0f 100644 --- a/packages/cli/tests/images/build.js +++ b/packages/cli/tests/images/build.js @@ -7,18 +7,18 @@ exports.default = { 'assets/icons/mstile-150x150.png': 9050, 'assets/favicon.ico': 15086, - 'ssr-build/ssr-bundle.77c49.css': 1281, - 'ssr-build/ssr-bundle.77c49.css.map': 2081, + 'ssr-build/ssr-bundle.dba70.css': 1281, + 'ssr-build/ssr-bundle.dba70.css.map': 2081, 'ssr-build/ssr-bundle.js': 26049, 'ssr-build/ssr-bundle.js.map': 59971, 'ssr-build/asset-manifest.json': 170, - 'bundle.465d5.js': 21563, - 'bundle.465d5.js.map': 86009, - 'bundle.465d5.legacy.js': 22586, - 'bundle.465d5.legacy.js.map': 107151, - 'bundle.9bde9.css': 945, - 'bundle.9bde9.css.map': 1758, + 'bundle.a6547.js': 21560, + 'bundle.a6547.js.map': 85822, + 'bundle.a6547.legacy.js': 22549, + 'bundle.a6547.legacy.js.map': 106841, + 'bundle.354c3.css': 945, + 'bundle.354c3.css.map': 1758, 'dom-polyfills.8a933.legacy.js': 5221, 'dom-polyfills.8a933.legacy.js.map': 18676, @@ -31,31 +31,21 @@ exports.default = { 'push-manifest.json': 450, 'asset-manifest.json': 1729, - 'route-home.chunk.040d2.js': 307, - 'route-home.chunk.040d2.js.map': 1684, - 'route-home.chunk.040d2.legacy.js': 364, - 'route-home.chunk.040d2.legacy.js.map': 1982, - 'route-home.chunk.f1c94.css': 112, - 'route-home.chunk.f1c94.css.map': 224, + 'route-home.chunk.f910e.js': 307, + 'route-home.chunk.f910e.js.map': 1516, + 'route-home.chunk.f910e.legacy.js': 347, + 'route-home.chunk.f910e.legacy.js.map': 1770, + 'route-home.chunk.6eaee.css': 112, + 'route-home.chunk.6eaee.css.map': 224, - 'route-profile.chunk.8c3bd.js': 3121, - 'route-profile.chunk.8c3bd.js.map': 12280, - 'route-profile.chunk.8c3bd.legacy.js': 3266, - 'route-profile.chunk.8c3bd.legacy.js.map': 15684, - 'route-profile.chunk.e0d39.css': 118, - 'route-profile.chunk.e0d39.css.map': 231, + 'route-profile.chunk.ef912.js': 3106, + 'route-profile.chunk.ef912.js.map': 12220, + 'route-profile.chunk.ef912.legacy.js': 3243, + 'route-profile.chunk.ef912.legacy.js.map': 15558, + 'route-profile.chunk.0af3e.css': 118, + 'route-profile.chunk.0af3e.css.map': 231, }; -exports.sass = ` - -
-

Header on background

-

Paragraph on background

-
- {{ ... }} - -`; - exports.prerender = {}; exports.prerender.heads = {}; diff --git a/packages/cli/tests/images/create.js b/packages/cli/tests/images/create.js index 6cd269512..05b0f1343 100644 --- a/packages/cli/tests/images/create.js +++ b/packages/cli/tests/images/create.js @@ -13,13 +13,13 @@ exports.default = [ 'src/assets/icons/mstile-150x150.png', 'src/components/app.js', 'src/components/header/index.js', - 'src/components/header/style.css', + 'src/components/header/style.module.css', 'src/index.js', 'src/manifest.json', 'src/routes/home/index.js', - 'src/routes/home/style.css', + 'src/routes/home/style.module.css', 'src/routes/profile/index.js', - 'src/routes/profile/style.css', + 'src/routes/profile/style.module.css', 'src/style/index.css', 'src/sw.js', 'src/template.html', diff --git a/packages/cli/tests/subjects/css-auto-modules/components/index.js b/packages/cli/tests/subjects/css-auto-modules/components/index.js deleted file mode 100644 index 5a0b70c6f..000000000 --- a/packages/cli/tests/subjects/css-auto-modules/components/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { h } from 'preact'; -import styles from './style.css'; - -export default () =>

This is a fancy component!

; diff --git a/packages/cli/tests/subjects/css-auto-modules/components/style.css b/packages/cli/tests/subjects/css-auto-modules/components/style.css deleted file mode 100644 index c275a6d60..000000000 --- a/packages/cli/tests/subjects/css-auto-modules/components/style.css +++ /dev/null @@ -1,3 +0,0 @@ -.text { - color: tan; -} diff --git a/packages/cli/tests/subjects/css-auto-modules/routes/index.js b/packages/cli/tests/subjects/css-auto-modules/routes/index.js deleted file mode 100644 index 32c34e32d..000000000 --- a/packages/cli/tests/subjects/css-auto-modules/routes/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { h } from 'preact'; -import styles from './style.css'; - -export default () =>

This is a fancy route!

; diff --git a/packages/cli/tests/subjects/css-auto-modules/routes/style.css b/packages/cli/tests/subjects/css-auto-modules/routes/style.css deleted file mode 100644 index 65c9e2935..000000000 --- a/packages/cli/tests/subjects/css-auto-modules/routes/style.css +++ /dev/null @@ -1,3 +0,0 @@ -.text { - color: red; -} diff --git a/packages/cli/tests/subjects/css-auto-modules/index.js b/packages/cli/tests/subjects/css-modules/index.js similarity index 52% rename from packages/cli/tests/subjects/css-auto-modules/index.js rename to packages/cli/tests/subjects/css-modules/index.js index 70410436c..69d56069a 100644 --- a/packages/cli/tests/subjects/css-auto-modules/index.js +++ b/packages/cli/tests/subjects/css-modules/index.js @@ -1,14 +1,13 @@ import { h } from 'preact'; -import Component from './components'; -import Route from './routes'; -import './global.css'; + +import './style.css'; +import styles from './style.module.css'; export default () => { return (

This is an app with some fancy styles!

- - +

We can even use CSS Modules!

); }; diff --git a/packages/cli/tests/subjects/css-auto-modules/package.json b/packages/cli/tests/subjects/css-modules/package.json similarity index 100% rename from packages/cli/tests/subjects/css-auto-modules/package.json rename to packages/cli/tests/subjects/css-modules/package.json diff --git a/packages/cli/tests/subjects/css-auto-modules/global.css b/packages/cli/tests/subjects/css-modules/style.css similarity index 100% rename from packages/cli/tests/subjects/css-auto-modules/global.css rename to packages/cli/tests/subjects/css-modules/style.css diff --git a/packages/cli/tests/subjects/css-modules/style.module.css b/packages/cli/tests/subjects/css-modules/style.module.css new file mode 100644 index 000000000..de150dc20 --- /dev/null +++ b/packages/cli/tests/subjects/css-modules/style.module.css @@ -0,0 +1,3 @@ +.text { + color: blue; +} diff --git a/packages/cli/tests/subjects/css-sass/components/app/index.js b/packages/cli/tests/subjects/css-sass/components/app/index.js deleted file mode 100644 index 0b8a44f98..000000000 --- a/packages/cli/tests/subjects/css-sass/components/app/index.js +++ /dev/null @@ -1,11 +0,0 @@ -import { h } from 'preact'; -import style from './style.scss'; - -const App = () => ( -
-

Header on background

-

Paragraph on background

-
-); - -export default App; diff --git a/packages/cli/tests/subjects/css-sass/components/app/style.scss b/packages/cli/tests/subjects/css-sass/components/app/style.scss deleted file mode 100644 index cddec2546..000000000 --- a/packages/cli/tests/subjects/css-sass/components/app/style.scss +++ /dev/null @@ -1,3 +0,0 @@ -.background { - background: teal; -} diff --git a/packages/cli/tests/subjects/css-sass/index.js b/packages/cli/tests/subjects/css-sass/index.js index daf82edab..03c0944cc 100644 --- a/packages/cli/tests/subjects/css-sass/index.js +++ b/packages/cli/tests/subjects/css-sass/index.js @@ -1,4 +1,17 @@ import { h } from 'preact'; -import App from './components/app'; -export default () => ; +import './style.sass'; +import './style.scss'; +import sassStyles from './style.module.sass'; +import scssStyles from './style.module.scss'; + +export default () => { + return ( +
+

This is an app with some fancy styles!

+

+ We can even use CSS Modules! +

+
+ ); +}; diff --git a/packages/cli/tests/subjects/css-sass/style.module.sass b/packages/cli/tests/subjects/css-sass/style.module.sass new file mode 100644 index 000000000..d04dc647a --- /dev/null +++ b/packages/cli/tests/subjects/css-sass/style.module.sass @@ -0,0 +1,2 @@ +.text + color: blue diff --git a/packages/cli/tests/subjects/css-sass/style.module.scss b/packages/cli/tests/subjects/css-sass/style.module.scss new file mode 100644 index 000000000..819d1f77f --- /dev/null +++ b/packages/cli/tests/subjects/css-sass/style.module.scss @@ -0,0 +1,3 @@ +.text { + background: red; +} diff --git a/packages/cli/tests/subjects/css-sass/style.sass b/packages/cli/tests/subjects/css-sass/style.sass new file mode 100644 index 000000000..9fd33cbed --- /dev/null +++ b/packages/cli/tests/subjects/css-sass/style.sass @@ -0,0 +1,2 @@ +h1 + color: red diff --git a/packages/cli/tests/subjects/css-sass/style.scss b/packages/cli/tests/subjects/css-sass/style.scss new file mode 100644 index 000000000..b71406174 --- /dev/null +++ b/packages/cli/tests/subjects/css-sass/style.scss @@ -0,0 +1,3 @@ +h1 { + background: blue; +}