From b4e4bc354c81f3c44e28f14bffb1a3506d8304dd Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 25 Oct 2023 17:59:59 +0800 Subject: [PATCH 1/9] feat: init plugin-styled-components --- e2e/cases/styled-component/index.test.ts | 28 +++----- e2e/cases/styled-component/package.json | 3 +- .../core/src/rspack-provider/types/rspack.ts | 12 ++++ .../plugin-styled-components/CHANGELOG.md | 1 + packages/plugin-styled-components/LICENSE | 21 ++++++ packages/plugin-styled-components/README.md | 19 ++++++ .../plugin-styled-components/modern.config.ts | 3 + .../plugin-styled-components/package.json | 43 +++++++++++++ .../plugin-styled-components/src/index.ts | 64 +++++++++++++++++++ .../tests/index.test.ts | 16 +++++ .../plugin-styled-components/tsconfig.json | 9 +++ packages/webpack/package.json | 1 - packages/webpack/src/config/validate/tools.ts | 1 - packages/webpack/src/plugins/babel.ts | 25 -------- pnpm-lock.yaml | 28 ++++++++ 15 files changed, 227 insertions(+), 47 deletions(-) create mode 100644 packages/plugin-styled-components/CHANGELOG.md create mode 100644 packages/plugin-styled-components/LICENSE create mode 100644 packages/plugin-styled-components/README.md create mode 100644 packages/plugin-styled-components/modern.config.ts create mode 100644 packages/plugin-styled-components/package.json create mode 100644 packages/plugin-styled-components/src/index.ts create mode 100644 packages/plugin-styled-components/tests/index.test.ts create mode 100644 packages/plugin-styled-components/tsconfig.json diff --git a/e2e/cases/styled-component/index.test.ts b/e2e/cases/styled-component/index.test.ts index e8d30a065b..1f8bef5b5b 100644 --- a/e2e/cases/styled-component/index.test.ts +++ b/e2e/cases/styled-component/index.test.ts @@ -1,7 +1,7 @@ import path from 'path'; import { build } from '@scripts/shared'; -import { webpackOnlyTest } from '@scripts/helper'; -import { expect } from '@playwright/test'; +import { expect, test } from '@playwright/test'; +import { pluginStyledComponents } from '@rsbuild/plugin-styled-components'; const commonConfig = { cwd: __dirname, @@ -18,20 +18,8 @@ const commonConfig = { }, }; -const noStyledConfig = { - ...commonConfig, - rsbuildConfig: { - ...commonConfig.rsbuildConfig, - tools: { - ...commonConfig.rsbuildConfig.tools, - styledComponents: false as const, - }, - }, -}; - -// TODO: needs builtin:swc-loader -webpackOnlyTest('should allow to disable styled-components', async () => { - const rsbuild = await build(noStyledConfig); +test('should not compiled styled-components by default', async () => { + const rsbuild = await build(commonConfig); const files = await rsbuild.unwrapOutputJSON(); const content = @@ -39,9 +27,11 @@ webpackOnlyTest('should allow to disable styled-components', async () => { expect(content).toContain('div`'); }); -// TODO: needs builtin:swc-loader -webpackOnlyTest('should transform styled-components by default', async () => { - const rsbuild = await build(commonConfig); +test('should transform styled-components', async () => { + const rsbuild = await build({ + ...commonConfig, + plugins: [pluginStyledComponents()], + }); const files = await rsbuild.unwrapOutputJSON(); const content = diff --git a/e2e/cases/styled-component/package.json b/e2e/cases/styled-component/package.json index 180e2d22f0..627538cd80 100644 --- a/e2e/cases/styled-component/package.json +++ b/e2e/cases/styled-component/package.json @@ -2,6 +2,7 @@ "name": "@e2e/styled-component", "private": true, "dependencies": { - "styled-components": "^6.0.0" + "styled-components": "^6.0.0", + "@rsbuild/plugin-styled-components": "workspace:*" } } diff --git a/packages/core/src/rspack-provider/types/rspack.ts b/packages/core/src/rspack-provider/types/rspack.ts index 7a9af6b7f1..93a843c908 100644 --- a/packages/core/src/rspack-provider/types/rspack.ts +++ b/packages/core/src/rspack-provider/types/rspack.ts @@ -101,6 +101,18 @@ export type BuiltinSwcLoaderOptions = { 'react' | 'decorator' | 'presetEnv' | 'emotion' | 'relay' > & { import?: BuiltinsOptions['pluginImport']; + styledComponents?: { + displayName?: boolean; + ssr?: boolean; + fileName?: boolean; + meaninglessFileNames?: string[]; + namespace?: string; + topLevelImportPaths?: string[]; + transpileTemplateLiterals?: boolean; + minify?: boolean; + pure?: boolean; + cssProps?: boolean; + }; }; }; diff --git a/packages/plugin-styled-components/CHANGELOG.md b/packages/plugin-styled-components/CHANGELOG.md new file mode 100644 index 0000000000..df69c244bc --- /dev/null +++ b/packages/plugin-styled-components/CHANGELOG.md @@ -0,0 +1 @@ +# @rsbuild/plugin-styled-components diff --git a/packages/plugin-styled-components/LICENSE b/packages/plugin-styled-components/LICENSE new file mode 100644 index 0000000000..82d38c25b5 --- /dev/null +++ b/packages/plugin-styled-components/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023-present Bytedance, Inc. and its affiliates. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/plugin-styled-components/README.md b/packages/plugin-styled-components/README.md new file mode 100644 index 0000000000..6df1b99e33 --- /dev/null +++ b/packages/plugin-styled-components/README.md @@ -0,0 +1,19 @@ +

+ Rsbuild Logo +

+ +# Rsbuild + +Unleash the power of Rspack with the out-of-the-box build tool. + +## Documentation + +https://rsbuild.dev/ + +## Contributing + +Please read the [Contributing Guide](https://github.com/web-infra-dev/rsbuild/blob/main/CONTRIBUTING.md). + +## License + +Rsbuild is [MIT licensed](https://github.com/web-infra-dev/rsbuild/blob/main/LICENSE). diff --git a/packages/plugin-styled-components/modern.config.ts b/packages/plugin-styled-components/modern.config.ts new file mode 100644 index 0000000000..52cae05a53 --- /dev/null +++ b/packages/plugin-styled-components/modern.config.ts @@ -0,0 +1,3 @@ +import baseConfig from '../../scripts/modern.base.config'; + +export default baseConfig; diff --git a/packages/plugin-styled-components/package.json b/packages/plugin-styled-components/package.json new file mode 100644 index 0000000000..7ab4fccdaf --- /dev/null +++ b/packages/plugin-styled-components/package.json @@ -0,0 +1,43 @@ +{ + "name": "@rsbuild/plugin-styled-components", + "version": "0.0.7", + "description": "styled-components plugin for Rsbuild", + "repository": { + "type": "git", + "url": "https://github.com/web-infra-dev/rsbuild", + "directory": "packages/plugin-styled-components" + }, + "main": "./dist/index.js", + "types": "./src/index.ts", + "scripts": { + "dev": "modern build --watch", + "build": "modern build" + }, + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "files": [ + "dist" + ], + "license": "MIT", + "dependencies": { + "@modern-js/utils": "^2.37.1", + "@rsbuild/shared": "workspace:*" + }, + "devDependencies": { + "@rsbuild/core": "workspace:*", + "@rsbuild/test-helper": "workspace:*", + "@rsbuild/webpack": "workspace:*", + "@types/node": "^16", + "typescript": "^5" + }, + "publishConfig": { + "registry": "https://registry.npmjs.org/", + "access": "public", + "provenance": true, + "types": "./dist/index.d.ts" + } +} diff --git a/packages/plugin-styled-components/src/index.ts b/packages/plugin-styled-components/src/index.ts new file mode 100644 index 0000000000..cf80714bd8 --- /dev/null +++ b/packages/plugin-styled-components/src/index.ts @@ -0,0 +1,64 @@ +import { + DefaultRsbuildPlugin, + getDefaultStyledComponentsConfig, + mergeChainedOptions, +} from '@rsbuild/shared'; + +type StyledComponentsOptions = { + displayName?: boolean; + ssr?: boolean; + fileName?: boolean; + meaninglessFileNames?: string[]; + namespace?: string; + topLevelImportPaths?: string[]; + transpileTemplateLiterals?: boolean; + minify?: boolean; + pure?: boolean; + cssProps?: boolean; +}; + +export const pluginStyledComponents = ( + userConfig: StyledComponentsOptions = {}, +): DefaultRsbuildPlugin => ({ + name: 'plugin-styled-components', + + setup(api) { + const { bundlerType } = api.context; + + if (bundlerType !== 'rspack') { + return; + } + + api.modifyBundlerChain(async (chain, { CHAIN_ID, isProd, target }) => { + const rule = chain.module.rule(CHAIN_ID.RULE.JS); + const isSSR = target === 'node'; + + const styledComponentsOptions = mergeChainedOptions< + StyledComponentsOptions, + {} + >(getDefaultStyledComponentsConfig(isProd, isSSR), userConfig); + + if (!styledComponentsOptions) { + return; + } + + rule.use(CHAIN_ID.USE.SWC).tap((options) => { + options.rspackExperiments ??= {}; + options.rspackExperiments.styledComponents = styledComponentsOptions; + return options; + }); + + if (chain.module.rules.has(CHAIN_ID.RULE.JS_DATA_URI)) { + chain.module + .rule(CHAIN_ID.RULE.JS_DATA_URI) + .use(CHAIN_ID.USE.SWC) + .tap((options) => { + options.rspackExperiments ??= {}; + options.rspackExperiments.styledComponents = + styledComponentsOptions; + return options; + }); + } + }); + }, +}); diff --git a/packages/plugin-styled-components/tests/index.test.ts b/packages/plugin-styled-components/tests/index.test.ts new file mode 100644 index 0000000000..8da2c87a94 --- /dev/null +++ b/packages/plugin-styled-components/tests/index.test.ts @@ -0,0 +1,16 @@ +import { expect, describe, it, vi } from 'vitest'; +import { pluginStyledComponents } from '../src'; +import { createStubRsbuild } from '@rsbuild/test-helper'; + +describe('plugins/styled-components', () => { + it('should works in rspack mode', async () => { + const rsbuild = await createStubRsbuild({ + rsbuildConfig: {}, + }); + + rsbuild.addPlugins([pluginStyledComponents()]); + const config = await rsbuild.unwrapConfig(); + + expect(config).toMatchSnapshot(); + }); +}); diff --git a/packages/plugin-styled-components/tsconfig.json b/packages/plugin-styled-components/tsconfig.json new file mode 100644 index 0000000000..63a57a9d30 --- /dev/null +++ b/packages/plugin-styled-components/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@rsbuild/tsconfig/base", + "compilerOptions": { + "outDir": "./dist", + "baseUrl": "./" + }, + "include": ["src"], + "exclude": ["./tests/fixtures"] +} diff --git a/packages/webpack/package.json b/packages/webpack/package.json index eef01c677e..2332c1784c 100644 --- a/packages/webpack/package.json +++ b/packages/webpack/package.json @@ -64,7 +64,6 @@ "@rsbuild/babel-preset": "workspace:*", "@rsbuild/shared": "workspace:*", "babel-plugin-import": "1.13.5", - "babel-plugin-styled-components": "1.13.3", "caniuse-lite": "^1.0.30001520", "html-webpack-plugin": "5.5.3", "lodash": "^4.17.21", diff --git a/packages/webpack/src/config/validate/tools.ts b/packages/webpack/src/config/validate/tools.ts index c8fb45c478..ddaf25c6bd 100644 --- a/packages/webpack/src/config/validate/tools.ts +++ b/packages/webpack/src/config/validate/tools.ts @@ -24,7 +24,6 @@ export const toolsConfigSchema: z.ZodType = sharedToolsConfigSchema z.any(), z.object({ entryName: z.string(), entryValue: z.any() }), ), - styledComponents: z.chained(z.any()), cssLoader: z.chained(z.any(), z.object({ addPlugins: z.function() })), styleLoader: z.chained(z.any()), cssExtract: z.partialObj({ diff --git a/packages/webpack/src/plugins/babel.ts b/packages/webpack/src/plugins/babel.ts index eb16ccfa8a..56771338dd 100644 --- a/packages/webpack/src/plugins/babel.ts +++ b/packages/webpack/src/plugins/babel.ts @@ -10,7 +10,6 @@ import { mergeChainedOptions, applyScriptCondition, getBrowserslistWithDefault, - getDefaultStyledComponentsConfig, } from '@rsbuild/shared'; import { getCompiledPath } from '../shared'; @@ -179,30 +178,6 @@ function applyPluginLodash(config: BabelConfig, transformLodash?: boolean) { } } -function applyPluginStyledComponents( - babelConfig: BabelConfig, - rsbuildConfig: NormalizedConfig, - isProd: boolean, -) { - const styledComponentsOptions = - rsbuildConfig.tools.styledComponents !== false - ? mergeChainedOptions( - getDefaultStyledComponentsConfig( - isProd, - isUseSSRBundle(rsbuildConfig), - ), - rsbuildConfig.tools.styledComponents, - ) - : false; - - if (styledComponentsOptions) { - babelConfig.plugins?.push([ - require.resolve('babel-plugin-styled-components'), - styledComponentsOptions, - ]); - } -} - function applyPluginImport( config: BabelConfig, pluginImport?: false | TransformImport[], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e96a1bf757..1673977da8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -224,6 +224,9 @@ importers: e2e/cases/styled-component: dependencies: + '@rsbuild/plugin-styled-components': + specifier: workspace:* + version: link:../../../packages/plugin-styled-components styled-components: specifier: ^6.0.0 version: 6.1.0(react-dom@18.2.0)(react@18.2.0) @@ -551,6 +554,31 @@ importers: specifier: ^5 version: 5.2.2 + packages/plugin-styled-components: + dependencies: + '@modern-js/utils': + specifier: ^2.37.1 + version: 2.37.1 + '@rsbuild/shared': + specifier: workspace:* + version: link:../shared + devDependencies: + '@rsbuild/core': + specifier: workspace:* + version: link:../core + '@rsbuild/test-helper': + specifier: workspace:* + version: link:../test-helper + '@rsbuild/webpack': + specifier: workspace:* + version: link:../webpack + '@types/node': + specifier: ^16 + version: 16.18.59 + typescript: + specifier: ^5 + version: 5.2.2 + packages/plugin-stylus: dependencies: '@rsbuild/shared': From fe85280de43ae73f6feaebce9aaf17ebfe7283b7 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 25 Oct 2023 18:02:42 +0800 Subject: [PATCH 2/9] fix: support webpack --- .../document/docs/en/config/options/tools.mdx | 6 - .../docs/en/guide/advanced/rspack-start.mdx | 1 - .../shared/config/tools/styledComponents.md | 2 - .../document/docs/zh/config/options/tools.mdx | 6 - .../docs/zh/guide/advanced/rspack-start.mdx | 1 - .../shared/config/tools/styledComponents.md | 2 - .../plugin-styled-components/package.json | 3 +- .../plugin-styled-components/src/index.ts | 73 +++++--- .../tests/__snapshots__/index.test.ts.snap | 159 ++++++++++++++++++ .../tests/index.test.ts | 28 ++- packages/plugin-swc/src/utils.ts | 1 + packages/webpack/src/types/config/tools.ts | 18 -- 12 files changed, 238 insertions(+), 62 deletions(-) create mode 100644 packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap diff --git a/packages/document/docs/en/config/options/tools.mdx b/packages/document/docs/en/config/options/tools.mdx index b3fe27749c..f82c837f09 100644 --- a/packages/document/docs/en/config/options/tools.mdx +++ b/packages/document/docs/en/config/options/tools.mdx @@ -84,12 +84,6 @@ import StyleLoader from '@en/shared/config/tools/styleLoader.md'; -## tools.styledComponents - -import StyledComponents from '@en/shared/config/tools/styledComponents.md'; - - - ## tools.terser import Terser from '@en/shared/config/tools/terser.md'; diff --git a/packages/document/docs/en/guide/advanced/rspack-start.mdx b/packages/document/docs/en/guide/advanced/rspack-start.mdx index 9b87d7490c..95e425285b 100644 --- a/packages/document/docs/en/guide/advanced/rspack-start.mdx +++ b/packages/document/docs/en/guide/advanced/rspack-start.mdx @@ -113,7 +113,6 @@ Unsupported configurations and capabilities include: - [tools.terser](/config/options/tools.html#toolsterser) - [tools.cssExtract](/config/options/tools.html#toolscssextract) - [tools.cssLoader](/config/options/tools.html#toolscssloader) (Only supported when [disableCssExtract](/config/options/output.html#outputdisablecssextract) is true) -- [tools.styledComponents](/config/options/tools.html#toolsstyledcomponents) - [tools.tsLoader](/config/options/tools.html#toolstsloader) - [tools.webpack](/config/options/tools.html#toolswebpack):use [tools.rspack](/config/options/tools#toolsrspack) instead. - [tools.webpackChain](/config/options/tools.html#toolswebpackchain):use [tools.bundlerChain](/config/options/tools#toolsbundlerchain) instead. diff --git a/packages/document/docs/en/shared/config/tools/styledComponents.md b/packages/document/docs/en/shared/config/tools/styledComponents.md index e389b0ae7c..4eb10f20d6 100644 --- a/packages/document/docs/en/shared/config/tools/styledComponents.md +++ b/packages/document/docs/en/shared/config/tools/styledComponents.md @@ -12,8 +12,6 @@ } ``` -- **Bundler:** `only support webpack` - `tools.styledComponents` config is corresponding to [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components), or [@swc/plugin-styled-components](https://github.com/swc-project/plugins/tree/main/packages/styled-components) when using SWC plugin. When the value is an Object, use the Object.assign function to merge with the default config. For example: diff --git a/packages/document/docs/zh/config/options/tools.mdx b/packages/document/docs/zh/config/options/tools.mdx index 09a70a05b9..132e9a73bc 100644 --- a/packages/document/docs/zh/config/options/tools.mdx +++ b/packages/document/docs/zh/config/options/tools.mdx @@ -84,12 +84,6 @@ import StyleLoader from '@zh/shared/config/tools/styleLoader.md'; -## tools.styledComponents - -import StyledComponents from '@zh/shared/config/tools/styledComponents.md'; - - - ## tools.terser import Terser from '@zh/shared/config/tools/terser.md'; diff --git a/packages/document/docs/zh/guide/advanced/rspack-start.mdx b/packages/document/docs/zh/guide/advanced/rspack-start.mdx index 1ceb4cac5b..879333b680 100644 --- a/packages/document/docs/zh/guide/advanced/rspack-start.mdx +++ b/packages/document/docs/zh/guide/advanced/rspack-start.mdx @@ -113,7 +113,6 @@ Rsbuild 旨在消除不同打包工具之间的主要差异,帮助用户以较 - [tools.terser](/config/options/tools.html#toolsterser) - [tools.cssExtract](/config/options/tools.html#toolscssextract) - [tools.cssLoader](/config/options/tools.html#toolscssloader) (仅在 [disableCssExtract](/config/options/output.html#outputdisablecssextract) 时支持) -- [tools.styledComponents](/config/options/tools.html#toolsstyledcomponents) - [tools.tsLoader](/config/options/tools.html#toolstsloader) - [tools.webpack](/config/options/tools.html#toolswebpack):使用 [tools.rspack](/config/options/tools#toolsrspack) 代替。 - [tools.webpackChain](/config/options/tools.html#toolswebpackchain):使用 [tools.bundlerChain](/config/options/tools#toolsbundlerchain) 代替。 diff --git a/packages/document/docs/zh/shared/config/tools/styledComponents.md b/packages/document/docs/zh/shared/config/tools/styledComponents.md index deed47f11f..4e73cc37e4 100644 --- a/packages/document/docs/zh/shared/config/tools/styledComponents.md +++ b/packages/document/docs/zh/shared/config/tools/styledComponents.md @@ -12,8 +12,6 @@ } ``` -- **打包工具:** `仅支持 webpack` - 对应 [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components) 或使用 SWC 时 [@swc/plugin-styled-components](https://github.com/swc-project/plugins/tree/main/packages/styled-components) 的配置。 值为 `Object` 类型时,利用 Object.assign 函数与默认配置合并。比如: ```js diff --git a/packages/plugin-styled-components/package.json b/packages/plugin-styled-components/package.json index 7ab4fccdaf..a91494b66a 100644 --- a/packages/plugin-styled-components/package.json +++ b/packages/plugin-styled-components/package.json @@ -25,7 +25,8 @@ "license": "MIT", "dependencies": { "@modern-js/utils": "^2.37.1", - "@rsbuild/shared": "workspace:*" + "@rsbuild/shared": "workspace:*", + "babel-plugin-styled-components": "1.13.3" }, "devDependencies": { "@rsbuild/core": "workspace:*", diff --git a/packages/plugin-styled-components/src/index.ts b/packages/plugin-styled-components/src/index.ts index cf80714bd8..5aa5776811 100644 --- a/packages/plugin-styled-components/src/index.ts +++ b/packages/plugin-styled-components/src/index.ts @@ -2,8 +2,12 @@ import { DefaultRsbuildPlugin, getDefaultStyledComponentsConfig, mergeChainedOptions, + ChainedConfig, } from '@rsbuild/shared'; +/** + * the options of [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components) or [rspackExperiments.styledComponents](https://www.rspack.dev/guide/loader.html#optionsrspackexperimentsstyledcomponents). + */ type StyledComponentsOptions = { displayName?: boolean; ssr?: boolean; @@ -18,19 +22,14 @@ type StyledComponentsOptions = { }; export const pluginStyledComponents = ( - userConfig: StyledComponentsOptions = {}, + userConfig: ChainedConfig = {}, ): DefaultRsbuildPlugin => ({ name: 'plugin-styled-components', setup(api) { - const { bundlerType } = api.context; - - if (bundlerType !== 'rspack') { - return; - } - api.modifyBundlerChain(async (chain, { CHAIN_ID, isProd, target }) => { - const rule = chain.module.rule(CHAIN_ID.RULE.JS); + const { bundlerType } = api.context; + const isSSR = target === 'node'; const styledComponentsOptions = mergeChainedOptions< @@ -42,22 +41,50 @@ export const pluginStyledComponents = ( return; } - rule.use(CHAIN_ID.USE.SWC).tap((options) => { - options.rspackExperiments ??= {}; - options.rspackExperiments.styledComponents = styledComponentsOptions; - return options; - }); + if (bundlerType === 'rspack') { + const rule = chain.module.rule(CHAIN_ID.RULE.JS); + + rule.use(CHAIN_ID.USE.SWC).tap((options) => { + options.rspackExperiments ??= {}; + options.rspackExperiments.styledComponents = styledComponentsOptions; + return options; + }); + + if (chain.module.rules.has(CHAIN_ID.RULE.JS_DATA_URI)) { + chain.module + .rule(CHAIN_ID.RULE.JS_DATA_URI) + .use(CHAIN_ID.USE.SWC) + .tap((options) => { + options.rspackExperiments ??= {}; + options.rspackExperiments.styledComponents = + styledComponentsOptions; + return options; + }); + } + } else { + const rule = chain.module.rule(CHAIN_ID.RULE.JS); + rule.use(CHAIN_ID.USE.BABEL).tap((babelConfig) => { + babelConfig.plugins ??= []; + babelConfig.plugins.push([ + require.resolve('babel-plugin-styled-components'), + styledComponentsOptions, + ]); + return babelConfig; + }); - if (chain.module.rules.has(CHAIN_ID.RULE.JS_DATA_URI)) { - chain.module - .rule(CHAIN_ID.RULE.JS_DATA_URI) - .use(CHAIN_ID.USE.SWC) - .tap((options) => { - options.rspackExperiments ??= {}; - options.rspackExperiments.styledComponents = - styledComponentsOptions; - return options; - }); + if (chain.module.rules.has(CHAIN_ID.RULE.JS_DATA_URI)) { + chain.module + .rule(CHAIN_ID.RULE.JS_DATA_URI) + .use(CHAIN_ID.USE.BABEL) + .tap((babelConfig) => { + babelConfig.plugins ??= []; + babelConfig.plugins.push([ + require.resolve('babel-plugin-styled-components'), + styledComponentsOptions, + ]); + return babelConfig; + }); + } } }); }, diff --git a/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap b/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap new file mode 100644 index 0000000000..719ad3dea8 --- /dev/null +++ b/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap @@ -0,0 +1,159 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`plugins/styled-components > should works in rspack mode 1`] = ` +{ + "exclude": [ + "/node_modules//core-js", + ], + "include": [ + { + "and": [ + "", + { + "not": /\\[\\\\\\\\/\\]node_modules\\[\\\\\\\\/\\]/, + }, + ], + }, + ], + "test": /\\\\\\.\\(js\\|mjs\\|cjs\\|jsx\\)\\$\\|\\\\\\.\\(ts\\|mts\\|cts\\|tsx\\)\\$/, + "type": "javascript/auto", + "use": [ + { + "loader": "builtin:swc-loader", + "options": { + "env": { + "coreJs": "3.32", + "mode": "entry", + "targets": [ + "chrome >= 87", + "edge >= 88", + "firefox >= 78", + "safari >= 14", + ], + }, + "exclude": [], + "inlineSourcesContent": true, + "isModule": "unknown", + "jsc": { + "externalHelpers": true, + "parser": { + "decorators": true, + "syntax": "typescript", + "tsx": true, + }, + "transform": { + "decoratorMetadata": true, + "legacyDecorator": true, + }, + }, + "minify": false, + "rspackExperiments": { + "styledComponents": { + "displayName": true, + "pure": false, + "ssr": false, + "transpileTemplateLiterals": true, + }, + }, + "sourceMaps": true, + }, + }, + ], +} +`; + +exports[`plugins/styled-components > should works in webpack mode 1`] = ` +{ + "include": [ + { + "and": [ + "", + { + "not": /\\[\\\\\\\\/\\]node_modules\\[\\\\\\\\/\\]/, + }, + ], + }, + ], + "test": /\\\\\\.\\(js\\|mjs\\|cjs\\|jsx\\)\\$\\|\\\\\\.\\(ts\\|mts\\|cts\\|tsx\\)\\$/, + "use": [ + { + "loader": "/packages/shared/compiled/babel-loader", + "options": { + "babelrc": false, + "compact": false, + "configFile": false, + "plugins": [ + [ + "/node_modules//@babel/plugin-proposal-decorators/lib/index.js", + { + "version": "legacy", + }, + ], + "/node_modules//@babel/plugin-proposal-export-default-from/lib/index.js", + "/node_modules//@babel/plugin-proposal-partial-application/lib/index.js", + [ + "/node_modules//@babel/plugin-proposal-pipeline-operator/lib/index.js", + { + "proposal": "minimal", + }, + ], + [ + "/node_modules//@babel/plugin-transform-runtime/lib/index.js", + { + "useESModules": true, + "version": "7.23.2", + }, + ], + "/packages/babel-preset/dist/pluginLockCorejsVersion", + [ + "/packages/webpack/compiled/babel-plugin-lodash", + {}, + ], + [ + "/node_modules//babel-plugin-styled-components/lib/index.js", + { + "displayName": true, + "pure": false, + "ssr": false, + "transpileTemplateLiterals": true, + }, + ], + ], + "presets": [ + [ + "/node_modules//@babel/preset-env/lib/index.js", + { + "bugfixes": true, + "corejs": { + "proposals": true, + "version": "3.32", + }, + "exclude": [ + "transform-typeof-symbol", + ], + "modules": "commonjs", + "targets": [ + "chrome >= 87", + "edge >= 88", + "firefox >= 78", + "safari >= 14", + ], + "useBuiltIns": "entry", + }, + ], + [ + "/node_modules//@babel/preset-typescript/lib/index.js", + { + "allExtensions": true, + "allowDeclareFields": true, + "allowNamespaces": true, + "isTSX": true, + "optimizeConstEnums": true, + }, + ], + ], + }, + }, + ], +} +`; diff --git a/packages/plugin-styled-components/tests/index.test.ts b/packages/plugin-styled-components/tests/index.test.ts index 8da2c87a94..e0f8221f05 100644 --- a/packages/plugin-styled-components/tests/index.test.ts +++ b/packages/plugin-styled-components/tests/index.test.ts @@ -1,6 +1,8 @@ -import { expect, describe, it, vi } from 'vitest'; +import { expect, describe, it } from 'vitest'; import { pluginStyledComponents } from '../src'; import { createStubRsbuild } from '@rsbuild/test-helper'; +import { mergeRegex, JS_REGEX, TS_REGEX } from '@rsbuild/shared'; +import { webpackProvider } from '@rsbuild/webpack'; describe('plugins/styled-components', () => { it('should works in rspack mode', async () => { @@ -11,6 +13,28 @@ describe('plugins/styled-components', () => { rsbuild.addPlugins([pluginStyledComponents()]); const config = await rsbuild.unwrapConfig(); - expect(config).toMatchSnapshot(); + expect( + config.module.rules.find( + (r) => r.test.toString() === mergeRegex(JS_REGEX, TS_REGEX).toString(), + ), + ).toMatchSnapshot(); + }); + + it('should works in webpack mode', async () => { + const rsbuild = await createStubRsbuild({ + rsbuildConfig: {}, + provider: webpackProvider, + }); + + rsbuild.addPlugins([pluginStyledComponents()]); + const config = await rsbuild.unwrapConfig(); + + expect( + config.module.rules.find( + (r) => + r.test && + r.test.toString() === mergeRegex(JS_REGEX, TS_REGEX).toString(), + ), + ).toMatchSnapshot(); }); }); diff --git a/packages/plugin-swc/src/utils.ts b/packages/plugin-swc/src/utils.ts index ca16537930..14d5ddeb11 100644 --- a/packages/plugin-swc/src/utils.ts +++ b/packages/plugin-swc/src/utils.ts @@ -7,6 +7,7 @@ import { ModifyChainUtils, mergeChainedOptions, getBrowserslistWithDefault, + // TODO: move into plugin-styled-components getDefaultStyledComponentsConfig, } from '@rsbuild/shared'; import { Extensions } from '@modern-js/swc-plugins'; diff --git a/packages/webpack/src/types/config/tools.ts b/packages/webpack/src/types/config/tools.ts index 512adf3dde..fb82c98a77 100644 --- a/packages/webpack/src/types/config/tools.ts +++ b/packages/webpack/src/types/config/tools.ts @@ -27,20 +27,6 @@ export type ToolsTSLoaderConfig = ChainedConfig< { addIncludes: FileFilterUtil; addExcludes: FileFilterUtil } >; -export interface StyledComponentOptions { - pure?: boolean; - displayName?: boolean; - ssr?: boolean; - fileName?: boolean; - meaninglessFileNames?: string[]; - minify?: boolean; - transpileTemplateLiterals?: boolean; - namespace?: string; - topLevelImportPaths?: string[]; -} - -export type ToolsStyledComponentConfig = ChainedConfig; - export type ToolsCssExtractConfig = | CSSExtractOptions | ((options: CSSExtractOptions) => CSSExtractOptions | void); @@ -85,10 +71,6 @@ export interface ToolsConfig extends SharedToolsConfig { * Modify the options of [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin). */ htmlPlugin?: false | ToolsHtmlPluginConfig; - /** - * Modify the options of [babel-plugin-styled-components](https://github.com/styled-components/babel-plugin-styled-components). - */ - styledComponents?: false | ToolsStyledComponentConfig; /** * Modify the options of [mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin). */ From 161ffd0b9a0dc3183df70831bb939f6001a401aa Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Wed, 25 Oct 2023 18:43:52 +0800 Subject: [PATCH 3/9] fix: support webpack --- .../tests/__snapshots__/webpack.test.ts.snap | 36 ------ packages/plugin-swc/src/utils.ts | 2 + .../tests/__snapshots__/index.test.ts.snap | 36 ------ .../tests/__snapshots__/index.test.ts.snap | 36 ------ packages/webpack/src/plugins/babel.ts | 1 - .../__snapshots__/webpackConfig.test.ts.snap | 54 --------- .../plugins/__snapshots__/babel.test.ts.snap | 108 ------------------ .../__snapshots__/default.test.ts.snap | 72 ------------ 8 files changed, 2 insertions(+), 343 deletions(-) diff --git a/packages/plugin-react/tests/__snapshots__/webpack.test.ts.snap b/packages/plugin-react/tests/__snapshots__/webpack.test.ts.snap index fced58a394..1924c367e8 100644 --- a/packages/plugin-react/tests/__snapshots__/webpack.test.ts.snap +++ b/packages/plugin-react/tests/__snapshots__/webpack.test.ts.snap @@ -50,15 +50,6 @@ exports[`plugins/react > should work with babel-loader 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], [ "/node_modules//react-refresh/babel.js", { @@ -153,15 +144,6 @@ exports[`plugins/react > should work with babel-loader 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -481,15 +463,6 @@ exports[`plugins/react > should work with ts-loader 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -581,15 +554,6 @@ exports[`plugins/react > should work with ts-loader 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ diff --git a/packages/plugin-swc/src/utils.ts b/packages/plugin-swc/src/utils.ts index ad0e6a982a..a2ec05df3f 100644 --- a/packages/plugin-swc/src/utils.ts +++ b/packages/plugin-swc/src/utils.ts @@ -177,11 +177,13 @@ export async function applyPluginConfig( const isSSR = target === 'node'; if ( + // @ts-expect-error rsbuildConfig.tools.styledComponents !== false && swc.extensions?.styledComponents !== false ) { const styledComponentsOptions = mergeChainedOptions( getDefaultStyledComponentsConfig(isProd, isSSR), + // @ts-expect-error rsbuildConfig.tools.styledComponents, ); swc.extensions.styledComponents = { diff --git a/packages/plugin-vue-jsx/tests/__snapshots__/index.test.ts.snap b/packages/plugin-vue-jsx/tests/__snapshots__/index.test.ts.snap index 31180e8cf3..51d115297f 100644 --- a/packages/plugin-vue-jsx/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-vue-jsx/tests/__snapshots__/index.test.ts.snap @@ -50,15 +50,6 @@ exports[`plugin-vue-jsx > should allow to configure jsx babel plugin options 1`] "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], [ "/node_modules//@vue/babel-plugin-jsx/dist/index.js", { @@ -144,15 +135,6 @@ exports[`plugin-vue-jsx > should allow to configure jsx babel plugin options 1`] "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], [ "/node_modules//@vue/babel-plugin-jsx/dist/index.js", { @@ -252,15 +234,6 @@ exports[`plugin-vue-jsx > should apply jsx babel plugin correctly 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], [ "/node_modules//@vue/babel-plugin-jsx/dist/index.js", {}, @@ -344,15 +317,6 @@ exports[`plugin-vue-jsx > should apply jsx babel plugin correctly 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], [ "/node_modules//@vue/babel-plugin-jsx/dist/index.js", {}, diff --git a/packages/plugin-vue2-jsx/tests/__snapshots__/index.test.ts.snap b/packages/plugin-vue2-jsx/tests/__snapshots__/index.test.ts.snap index e7d1360c18..c0344a3e14 100644 --- a/packages/plugin-vue2-jsx/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-vue2-jsx/tests/__snapshots__/index.test.ts.snap @@ -50,15 +50,6 @@ exports[`plugin-vue2-jsx > should allow to configure jsx babel plugin options 1` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -144,15 +135,6 @@ exports[`plugin-vue2-jsx > should allow to configure jsx babel plugin options 1` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -252,15 +234,6 @@ exports[`plugin-vue2-jsx > should apply jsx babel plugin correctly 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -346,15 +319,6 @@ exports[`plugin-vue2-jsx > should apply jsx babel plugin correctly 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ diff --git a/packages/webpack/src/plugins/babel.ts b/packages/webpack/src/plugins/babel.ts index 9068620929..b926cecf62 100644 --- a/packages/webpack/src/plugins/babel.ts +++ b/packages/webpack/src/plugins/babel.ts @@ -98,7 +98,6 @@ export const pluginBabel = (): RsbuildPlugin => ({ baseBabelConfig, config.performance.transformLodash, ); - applyPluginStyledComponents(baseBabelConfig, config, isProd); const babelConfig = mergeChainedOptions( baseBabelConfig, diff --git a/packages/webpack/tests/__snapshots__/webpackConfig.test.ts.snap b/packages/webpack/tests/__snapshots__/webpackConfig.test.ts.snap index 13fd68a196..cf12a918d0 100644 --- a/packages/webpack/tests/__snapshots__/webpackConfig.test.ts.snap +++ b/packages/webpack/tests/__snapshots__/webpackConfig.test.ts.snap @@ -240,15 +240,6 @@ exports[`webpackConfig > should not have any pluginImport in Babel 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -328,15 +319,6 @@ exports[`webpackConfig > should not have any pluginImport in Babel 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -426,15 +408,6 @@ exports[`webpackConfig > should not set default pluginImport for Babel 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -514,15 +487,6 @@ exports[`webpackConfig > should not set default pluginImport for Babel 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -643,15 +607,6 @@ exports[`webpackConfig > should set proper pluginImport option in Babel 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -739,15 +694,6 @@ exports[`webpackConfig > should set proper pluginImport option in Babel 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ diff --git a/packages/webpack/tests/plugins/__snapshots__/babel.test.ts.snap b/packages/webpack/tests/plugins/__snapshots__/babel.test.ts.snap index 1ca114940a..a715fee802 100644 --- a/packages/webpack/tests/plugins/__snapshots__/babel.test.ts.snap +++ b/packages/webpack/tests/plugins/__snapshots__/babel.test.ts.snap @@ -59,15 +59,6 @@ exports[`plugin-babel > should add rule to compile Data URI when enable source.c "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -147,15 +138,6 @@ exports[`plugin-babel > should add rule to compile Data URI when enable source.c "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -242,15 +224,6 @@ exports[`plugin-babel > should adjust browserslist when target is node 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -314,15 +287,6 @@ exports[`plugin-babel > should adjust browserslist when target is node 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -410,15 +374,6 @@ exports[`plugin-babel > should apply exclude condition when using source.exclude "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -498,15 +453,6 @@ exports[`plugin-babel > should apply exclude condition when using source.exclude "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -608,15 +554,6 @@ exports[`plugin-babel > should override targets of babel-preset-env when using o "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -693,15 +630,6 @@ exports[`plugin-babel > should override targets of babel-preset-env when using o "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -792,15 +720,6 @@ exports[`plugin-babel > should set babel-loader 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -880,15 +799,6 @@ exports[`plugin-babel > should set babel-loader 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -986,15 +896,6 @@ exports[`plugin-babel > should set include/exclude 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -1074,15 +975,6 @@ exports[`plugin-babel > should set include/exclude 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ diff --git a/packages/webpack/tests/plugins/__snapshots__/default.test.ts.snap b/packages/webpack/tests/plugins/__snapshots__/default.test.ts.snap index d9107b1d53..9d9af1bbd7 100644 --- a/packages/webpack/tests/plugins/__snapshots__/default.test.ts.snap +++ b/packages/webpack/tests/plugins/__snapshots__/default.test.ts.snap @@ -256,15 +256,6 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -347,15 +338,6 @@ exports[`applyDefaultPlugins > should apply default plugins correctly 1`] = ` "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -969,15 +951,6 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when produ "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": true, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -1060,15 +1033,6 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when produ "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": true, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -1737,15 +1701,6 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": true, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -1812,15 +1767,6 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": true, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -2322,15 +2268,6 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": true, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ @@ -2413,15 +2350,6 @@ exports[`applyDefaultPlugins > should apply default plugins correctly when targe "/packages/webpack/compiled/babel-plugin-lodash", {}, ], - [ - "/node_modules//babel-plugin-styled-components/lib/index.js", - { - "displayName": true, - "pure": true, - "ssr": false, - "transpileTemplateLiterals": true, - }, - ], ], "presets": [ [ From d99e85882a179400f8ef47f77679892921943f35 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 26 Oct 2023 11:18:26 +0800 Subject: [PATCH 4/9] fix: support swc --- e2e/cases/styled-component/index.swc.test.ts | 5 +- e2e/package.json | 2 +- .../plugin-styled-components/package.json | 2 +- .../plugin-styled-components/src/index.ts | 62 +++++++--------- .../tests/__snapshots__/index.test.ts.snap | 73 ++++++++++++++++++- .../tests/index.test.ts | 21 +++++- packages/plugin-swc/src/plugin.ts | 2 +- packages/plugin-swc/src/utils.ts | 23 ------ packages/plugin-swc/tests/plugin.test.ts | 22 +++--- packages/shared/src/types/bundlerConfig.ts | 5 +- pnpm-lock.yaml | 12 +-- 11 files changed, 144 insertions(+), 85 deletions(-) diff --git a/e2e/cases/styled-component/index.swc.test.ts b/e2e/cases/styled-component/index.swc.test.ts index dd91c8a531..b40c2fd54e 100644 --- a/e2e/cases/styled-component/index.swc.test.ts +++ b/e2e/cases/styled-component/index.swc.test.ts @@ -2,6 +2,7 @@ import path from 'path'; import { build } from '@scripts/shared'; import { expect, test } from '@playwright/test'; import { pluginSwc } from '@rsbuild/plugin-swc'; +import { pluginStyledComponents } from '@rsbuild/plugin-styled-components'; const commonConfig = { cwd: __dirname, @@ -33,7 +34,7 @@ const noStyledConfig = { }, }; -test('should allow to disable styled-components when use swc plugin', async () => { +test('should not compiled styled-components by default when use swc plugin', async () => { const rsbuild = await build({ ...noStyledConfig, plugins: [pluginSwc()], @@ -53,7 +54,7 @@ test('should allow to disable styled-components when use swc plugin', async () = test('should transform styled-components by default when use swc plugin', async () => { const rsbuild = await build({ ...commonConfig, - plugins: [pluginSwc()], + plugins: [pluginSwc(), pluginStyledComponents()], }); const files = await rsbuild.unwrapOutputJSON(); diff --git a/e2e/package.json b/e2e/package.json index 14e9ed0eb7..e02d4fa854 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -6,7 +6,7 @@ "test": "pnpm run test:rspack && pnpm run test:webpack", "test:webpack": "PROVIDE_TYPE=webpack playwright test", "test:rspack": "playwright test", - "test:webpack-swc": "playwright test swc" + "test:webpack-swc": "PROVIDE_TYPE=webpack playwright test swc" }, "dependencies": { "lodash": "^4.17.21", diff --git a/packages/plugin-styled-components/package.json b/packages/plugin-styled-components/package.json index a91494b66a..f35d3e4b01 100644 --- a/packages/plugin-styled-components/package.json +++ b/packages/plugin-styled-components/package.json @@ -24,12 +24,12 @@ ], "license": "MIT", "dependencies": { - "@modern-js/utils": "^2.37.1", "@rsbuild/shared": "workspace:*", "babel-plugin-styled-components": "1.13.3" }, "devDependencies": { "@rsbuild/core": "workspace:*", + "@rsbuild/plugin-swc": "workspace:*", "@rsbuild/test-helper": "workspace:*", "@rsbuild/webpack": "workspace:*", "@types/node": "^16", diff --git a/packages/plugin-styled-components/src/index.ts b/packages/plugin-styled-components/src/index.ts index 5aa5776811..6b99fd6a9a 100644 --- a/packages/plugin-styled-components/src/index.ts +++ b/packages/plugin-styled-components/src/index.ts @@ -41,42 +41,29 @@ export const pluginStyledComponents = ( return; } - if (bundlerType === 'rspack') { - const rule = chain.module.rule(CHAIN_ID.RULE.JS); - - rule.use(CHAIN_ID.USE.SWC).tap((options) => { - options.rspackExperiments ??= {}; - options.rspackExperiments.styledComponents = styledComponentsOptions; - return options; - }); - - if (chain.module.rules.has(CHAIN_ID.RULE.JS_DATA_URI)) { - chain.module - .rule(CHAIN_ID.RULE.JS_DATA_URI) - .use(CHAIN_ID.USE.SWC) - .tap((options) => { - options.rspackExperiments ??= {}; - options.rspackExperiments.styledComponents = - styledComponentsOptions; - return options; - }); - } - } else { - const rule = chain.module.rule(CHAIN_ID.RULE.JS); - rule.use(CHAIN_ID.USE.BABEL).tap((babelConfig) => { - babelConfig.plugins ??= []; - babelConfig.plugins.push([ - require.resolve('babel-plugin-styled-components'), - styledComponentsOptions, - ]); - return babelConfig; - }); - - if (chain.module.rules.has(CHAIN_ID.RULE.JS_DATA_URI)) { - chain.module - .rule(CHAIN_ID.RULE.JS_DATA_URI) - .use(CHAIN_ID.USE.BABEL) - .tap((babelConfig) => { + [CHAIN_ID.RULE.JS, CHAIN_ID.RULE.JS_DATA_URI].forEach((ruleId) => { + if (chain.module.rules.has(ruleId)) { + const rule = chain.module.rule(ruleId); + // apply swc + if (rule.uses.has(CHAIN_ID.USE.SWC)) { + // apply rspack builtin:swc-loader + if (bundlerType === 'rspack') { + rule.use(CHAIN_ID.USE.SWC).tap((options) => { + options.rspackExperiments ??= {}; + options.rspackExperiments.styledComponents = + styledComponentsOptions; + return options; + }); + } else { + // apply webpack swc-plugin + rule.use(CHAIN_ID.USE.SWC).tap((swc) => { + swc.extensions.styledComponents = styledComponentsOptions; + return swc; + }); + } + } else if (rule.uses.has(CHAIN_ID.USE.BABEL)) { + // apply babel + rule.use(CHAIN_ID.USE.BABEL).tap((babelConfig) => { babelConfig.plugins ??= []; babelConfig.plugins.push([ require.resolve('babel-plugin-styled-components'), @@ -84,8 +71,9 @@ export const pluginStyledComponents = ( ]); return babelConfig; }); + } } - } + }); }); }, }); diff --git a/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap b/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap index 719ad3dea8..19d1e9b897 100644 --- a/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap @@ -62,7 +62,7 @@ exports[`plugins/styled-components > should works in rspack mode 1`] = ` } `; -exports[`plugins/styled-components > should works in webpack mode 1`] = ` +exports[`plugins/styled-components > should works in webpack babel mode 1`] = ` { "include": [ { @@ -157,3 +157,74 @@ exports[`plugins/styled-components > should works in webpack mode 1`] = ` ], } `; + +exports[`plugins/styled-components > should works in webpack swc mode 1`] = ` +{ + "include": [ + { + "and": [ + "", + { + "not": /\\[\\\\\\\\/\\]node_modules\\[\\\\\\\\/\\]/, + }, + ], + }, + ], + "test": /\\\\\\.\\(js\\|mjs\\|cjs\\|jsx\\)\\$\\|\\\\\\.\\(ts\\|mts\\|cts\\|tsx\\)\\$/, + "use": [ + { + "loader": "/packages/plugin-swc/dist/loader", + "options": { + "cwd": "", + "env": { + "coreJs": "3.32", + "mode": "entry", + "targets": [ + "chrome >= 87", + "edge >= 88", + "firefox >= 78", + "safari >= 14", + ], + }, + "extensions": { + "lockCorejsVersion": { + "corejs": "/node_modules//core-js", + "swcHelpers": "/node_modules//@swc/helpers", + }, + "lodash": { + "cwd": "", + "ids": [ + "lodash", + "lodash-es", + ], + }, + "styledComponents": { + "displayName": true, + "pure": false, + "ssr": false, + "transpileTemplateLiterals": true, + }, + }, + "inlineSourcesContent": true, + "jsc": { + "externalHelpers": true, + "parser": { + "decorators": true, + "syntax": "typescript", + "tsx": true, + }, + "preserveAllComments": true, + "transform": { + "react": { + "refresh": true, + "runtime": "classic", + }, + }, + }, + "minify": false, + "sourceMaps": true, + }, + }, + ], +} +`; diff --git a/packages/plugin-styled-components/tests/index.test.ts b/packages/plugin-styled-components/tests/index.test.ts index e0f8221f05..221c18c0a1 100644 --- a/packages/plugin-styled-components/tests/index.test.ts +++ b/packages/plugin-styled-components/tests/index.test.ts @@ -3,6 +3,7 @@ import { pluginStyledComponents } from '../src'; import { createStubRsbuild } from '@rsbuild/test-helper'; import { mergeRegex, JS_REGEX, TS_REGEX } from '@rsbuild/shared'; import { webpackProvider } from '@rsbuild/webpack'; +import { pluginSwc } from '@rsbuild/plugin-swc'; describe('plugins/styled-components', () => { it('should works in rspack mode', async () => { @@ -20,7 +21,7 @@ describe('plugins/styled-components', () => { ).toMatchSnapshot(); }); - it('should works in webpack mode', async () => { + it('should works in webpack babel mode', async () => { const rsbuild = await createStubRsbuild({ rsbuildConfig: {}, provider: webpackProvider, @@ -37,4 +38,22 @@ describe('plugins/styled-components', () => { ), ).toMatchSnapshot(); }); + + it('should works in webpack swc mode', async () => { + const rsbuild = await createStubRsbuild({ + rsbuildConfig: {}, + provider: webpackProvider, + }); + + rsbuild.addPlugins([pluginSwc(), pluginStyledComponents()]); + const config = await rsbuild.unwrapConfig(); + + expect( + config.module.rules.find( + (r) => + r.test && + r.test.toString() === mergeRegex(JS_REGEX, TS_REGEX).toString(), + ), + ).toMatchSnapshot(); + }); }); diff --git a/packages/plugin-swc/src/plugin.ts b/packages/plugin-swc/src/plugin.ts index 03c9b1e331..2dd6e6cc74 100644 --- a/packages/plugin-swc/src/plugin.ts +++ b/packages/plugin-swc/src/plugin.ts @@ -31,7 +31,7 @@ export const pluginSwc = (options: PluginSwcOptions = {}): RsbuildPlugin => ({ return; } - api.modifyWebpackChain(async (chain, utils) => { + api.modifyBundlerChain(async (chain, utils) => { const { CHAIN_ID, isProd } = utils; const rsbuildConfig = api.getNormalizedConfig(); const { rootPath } = api.context; diff --git a/packages/plugin-swc/src/utils.ts b/packages/plugin-swc/src/utils.ts index a2ec05df3f..7bedf545c7 100644 --- a/packages/plugin-swc/src/utils.ts +++ b/packages/plugin-swc/src/utils.ts @@ -5,10 +5,7 @@ import { logger, isUsingHMR, ModifyChainUtils, - mergeChainedOptions, getBrowserslistWithDefault, - // TODO: move into plugin-styled-components - getDefaultStyledComponentsConfig, } from '@rsbuild/shared'; import { Extensions } from '@modern-js/swc-plugins'; import { getDefaultSwcConfig } from './plugin'; @@ -174,26 +171,6 @@ export async function applyPluginConfig( ); } - const isSSR = target === 'node'; - - if ( - // @ts-expect-error - rsbuildConfig.tools.styledComponents !== false && - swc.extensions?.styledComponents !== false - ) { - const styledComponentsOptions = mergeChainedOptions( - getDefaultStyledComponentsConfig(isProd, isSSR), - // @ts-expect-error - rsbuildConfig.tools.styledComponents, - ); - swc.extensions.styledComponents = { - ...styledComponentsOptions, - ...(typeof swc.extensions.styledComponents === 'object' - ? swc.extensions?.styledComponents - : {}), - }; - } - const extensions: Extensions | OuterExtensions = (swc.extensions ??= {}); if (rsbuildConfig.source?.transformImport) { diff --git a/packages/plugin-swc/tests/plugin.test.ts b/packages/plugin-swc/tests/plugin.test.ts index ff32684640..9583c1dcf3 100644 --- a/packages/plugin-swc/tests/plugin.test.ts +++ b/packages/plugin-swc/tests/plugin.test.ts @@ -1,4 +1,4 @@ -import { createStubRsbuild } from '@rsbuild/webpack/stub'; +import { createStubRsbuild } from '@rsbuild/test-helper'; import { pluginSwc } from '../src'; import { pluginBabel } from '@rsbuild/webpack/plugin-babel'; import { applyPluginConfig } from '../src/utils'; @@ -20,7 +20,7 @@ describe('plugin-swc', () => { plugins: [pluginBabel(), pluginSwc()], rsbuildConfig: {}, }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config).toMatchSnapshot(); }); @@ -31,7 +31,7 @@ describe('plugin-swc', () => { plugins: [pluginBabel(), pluginSwc()], rsbuildConfig: {}, }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config.optimization).toMatchSnapshot(); process.env.NODE_ENV = 'test'; @@ -50,7 +50,7 @@ describe('plugin-swc', () => { }), ], }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config.optimization).toMatchSnapshot(); process.env.NODE_ENV = 'test'; @@ -71,7 +71,7 @@ describe('plugin-swc', () => { }), ], }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config.optimization).toMatchSnapshot(); process.env.NODE_ENV = 'test'; @@ -88,7 +88,7 @@ describe('plugin-swc', () => { }), ], }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config.optimization).toBeFalsy(); process.env.NODE_ENV = 'test'; }); @@ -108,7 +108,7 @@ describe('plugin-swc', () => { }), ], }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config.optimization).toBeFalsy(); process.env.NODE_ENV = 'test'; }); @@ -125,7 +125,7 @@ describe('plugin-swc', () => { }, }, }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config).toMatchSnapshot(); }); @@ -140,7 +140,7 @@ describe('plugin-swc', () => { }, }, }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config.module).toMatchSnapshot(); process.env.NODE_ENV = 'test'; @@ -153,7 +153,7 @@ describe('plugin-swc', () => { plugins: [pluginSwc()], target: ['node', 'service-worker', 'web', 'web-worker'], }); - const configs = await rsbuild.unwrapWebpackConfigs(); + const configs = await rsbuild.initConfigs(); for (const config of configs) { expect(config.module).toMatchSnapshot(); @@ -284,7 +284,7 @@ describe('plugin-swc', () => { ], rsbuildConfig: {}, }); - const config = await rsbuild.unwrapWebpackConfig(); + const config = await rsbuild.unwrapConfig(); expect(config.module!.rules).toMatchSnapshot(); }); diff --git a/packages/shared/src/types/bundlerConfig.ts b/packages/shared/src/types/bundlerConfig.ts index 2d3603a1b2..86f12b4cd1 100644 --- a/packages/shared/src/types/bundlerConfig.ts +++ b/packages/shared/src/types/bundlerConfig.ts @@ -207,7 +207,10 @@ export interface BundlerChain keyof WebpackChain['infrastructureLogging'] > >; - module: PickAndModifyThis; + module: PickAndModifyThis< + WebpackChain['module'], + 'rules' | 'rule' | 'delete' + >; } export type WebpackChainRule = WebpackChain.Rule; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1673977da8..900cad6dbd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -556,16 +556,19 @@ importers: packages/plugin-styled-components: dependencies: - '@modern-js/utils': - specifier: ^2.37.1 - version: 2.37.1 '@rsbuild/shared': specifier: workspace:* version: link:../shared + babel-plugin-styled-components: + specifier: 1.13.3 + version: 1.13.3(styled-components@6.1.0) devDependencies: '@rsbuild/core': specifier: workspace:* version: link:../core + '@rsbuild/plugin-swc': + specifier: workspace:* + version: link:../plugin-swc '@rsbuild/test-helper': specifier: workspace:* version: link:../test-helper @@ -944,9 +947,6 @@ importers: babel-plugin-import: specifier: 1.13.5 version: 1.13.5 - babel-plugin-styled-components: - specifier: 1.13.3 - version: 1.13.3(styled-components@6.1.0) caniuse-lite: specifier: ^1.0.30001520 version: 1.0.30001551 From 4275fa3146c68de9772bca639ee65d830bec21f8 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 26 Oct 2023 14:25:41 +0800 Subject: [PATCH 5/9] fix: snapshot --- .../tests/__snapshots__/plugin.test.ts.snap | 72 ------------------- 1 file changed, 72 deletions(-) diff --git a/packages/plugin-swc/tests/__snapshots__/plugin.test.ts.snap b/packages/plugin-swc/tests/__snapshots__/plugin.test.ts.snap index e28ccd9024..2a20f63204 100644 --- a/packages/plugin-swc/tests/__snapshots__/plugin.test.ts.snap +++ b/packages/plugin-swc/tests/__snapshots__/plugin.test.ts.snap @@ -47,12 +47,6 @@ exports[`plugin-swc > should apply source.include and source.exclude correctly 1 "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -110,12 +104,6 @@ exports[`plugin-swc > should apply source.include and source.exclude correctly 1 "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -176,12 +164,6 @@ exports[`plugin-swc > should disable react refresh when dev.hmr is false 1`] = ` "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -238,12 +220,6 @@ exports[`plugin-swc > should disable react refresh when target is not web 1`] = "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": true, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -303,12 +279,6 @@ exports[`plugin-swc > should disable react refresh when target is not web 2`] = "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -368,12 +338,6 @@ exports[`plugin-swc > should disable react refresh when target is not web 3`] = "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -433,12 +397,6 @@ exports[`plugin-swc > should disable react refresh when target is not web 4`] = "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -541,12 +499,6 @@ exports[`plugin-swc > should set multiple swc-loader 1`] = ` "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -605,12 +557,6 @@ exports[`plugin-swc > should set multiple swc-loader 1`] = ` "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -664,12 +610,6 @@ exports[`plugin-swc > should set multiple swc-loader 1`] = ` "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -757,12 +697,6 @@ exports[`plugin-swc > should set swc-loader 1`] = ` "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { @@ -820,12 +754,6 @@ exports[`plugin-swc > should set swc-loader 1`] = ` "lodash-es", ], }, - "styledComponents": { - "displayName": true, - "pure": false, - "ssr": false, - "transpileTemplateLiterals": true, - }, }, "inlineSourcesContent": true, "jsc": { From 0164034b7374b401747b0f742ef9a37309eccb22 Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 26 Oct 2023 14:29:22 +0800 Subject: [PATCH 6/9] docs: update changeset --- .changeset/metal-moose-complain.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/metal-moose-complain.md diff --git a/.changeset/metal-moose-complain.md b/.changeset/metal-moose-complain.md new file mode 100644 index 0000000000..44385eb821 --- /dev/null +++ b/.changeset/metal-moose-complain.md @@ -0,0 +1,5 @@ +--- +'@rsbuild/plugin-styled-components': patch +--- + +feat(plugin-styled-components): extract the styledComponents plugin as a standalone package From a8cb838b80441f06b2f17a4be9da91fcd7385c8a Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 26 Oct 2023 14:32:37 +0800 Subject: [PATCH 7/9] docs: update changeset --- .changeset/chilled-plums-lie.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/chilled-plums-lie.md diff --git a/.changeset/chilled-plums-lie.md b/.changeset/chilled-plums-lie.md new file mode 100644 index 0000000000..c871dc1aaa --- /dev/null +++ b/.changeset/chilled-plums-lie.md @@ -0,0 +1,5 @@ +--- +'@rsbuild/plugin-styled-components': patch +--- + +feat(plugin-styled-components): support styled-components in rspack mode From f221e4dfafc5c09718c8ce4fbc90d3d0d37f9c8a Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 26 Oct 2023 15:22:57 +0800 Subject: [PATCH 8/9] fix: compat builder-plugin-swc extensions.styledComponents params --- e2e/cases/styled-component/index.swc.test.ts | 25 +++++++++++++++++++- packages/plugin-swc/src/utils.ts | 13 ++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/e2e/cases/styled-component/index.swc.test.ts b/e2e/cases/styled-component/index.swc.test.ts index b40c2fd54e..d0d75c7e8d 100644 --- a/e2e/cases/styled-component/index.swc.test.ts +++ b/e2e/cases/styled-component/index.swc.test.ts @@ -51,7 +51,30 @@ test('should not compiled styled-components by default when use swc plugin', asy expect(content).toContain('div`'); }); -test('should transform styled-components by default when use swc plugin', async () => { +test('should transform styled-components when add extensions.styledComponents', async () => { + const rsbuild = await build({ + ...commonConfig, + plugins: [ + pluginSwc({ + extensions: { + styledComponents: {}, + }, + }), + ], + }); + const files = await rsbuild.unwrapOutputJSON(); + + const content = + files[ + Object.keys(files).find( + (file) => file.includes('static/js') && file.endsWith('.js'), + )! + ]; + + expect(content).toContain('div.withConfig'); +}); + +test('should transform styled-components when use pluginStyledComponents', async () => { const rsbuild = await build({ ...commonConfig, plugins: [pluginSwc(), pluginStyledComponents()], diff --git a/packages/plugin-swc/src/utils.ts b/packages/plugin-swc/src/utils.ts index 3ac10c3ed3..410587a390 100644 --- a/packages/plugin-swc/src/utils.ts +++ b/packages/plugin-swc/src/utils.ts @@ -7,6 +7,7 @@ import { getCoreJsVersion, getBrowserslistWithDefault, type ModifyChainUtils, + getDefaultStyledComponentsConfig, } from '@rsbuild/shared'; import { Extensions } from '@modern-js/swc-plugins'; import { getDefaultSwcConfig } from './plugin'; @@ -172,6 +173,18 @@ export async function applyPluginConfig( ); } + const isSSR = target === 'node'; + + // compat builder-plugin-swc extensions.styledComponents params + if (swc.extensions?.styledComponents) { + swc.extensions.styledComponents = { + ...getDefaultStyledComponentsConfig(isProd, isSSR), + ...(typeof swc.extensions.styledComponents === 'object' + ? swc.extensions?.styledComponents + : {}), + }; + } + const extensions: Extensions | OuterExtensions = (swc.extensions ??= {}); if (rsbuildConfig.source?.transformImport) { From 720e68c2aae7eae9e7fc0a0f642d3eb02ef83d9d Mon Sep 17 00:00:00 2001 From: "gaoyuan.1226" Date: Thu, 26 Oct 2023 16:30:08 +0800 Subject: [PATCH 9/9] fix: check ssr --- packages/plugin-react/src/antd.ts | 8 +- packages/plugin-react/src/arco.ts | 2 +- .../plugin-styled-components/src/index.ts | 3 +- .../tests/__snapshots__/index.test.ts.snap | 116 ++++++++++++++++++ .../tests/index.test.ts | 19 +++ packages/shared/src/utils.ts | 6 + 6 files changed, 145 insertions(+), 9 deletions(-) diff --git a/packages/plugin-react/src/antd.ts b/packages/plugin-react/src/antd.ts index d30f8861d4..936a40a8cc 100644 --- a/packages/plugin-react/src/antd.ts +++ b/packages/plugin-react/src/antd.ts @@ -1,4 +1,4 @@ -import type { RsbuildTarget, SharedRsbuildPluginAPI } from '@rsbuild/shared'; +import { useSSR, type SharedRsbuildPluginAPI } from '@rsbuild/shared'; const getAntdMajorVersion = (appDirectory: string) => { try { @@ -41,9 +41,3 @@ export const applyAntdSupport = (api: SharedRsbuildPluginAPI) => { } }); }; - -export function useSSR(target: RsbuildTarget | RsbuildTarget[]) { - return (Array.isArray(target) ? target : [target]).some((item) => - ['node', 'service-worker'].includes(item), - ); -} diff --git a/packages/plugin-react/src/arco.ts b/packages/plugin-react/src/arco.ts index 28a2b46609..353f59696a 100644 --- a/packages/plugin-react/src/arco.ts +++ b/packages/plugin-react/src/arco.ts @@ -1,6 +1,6 @@ -import { useSSR } from './antd'; import { isPackageInstalled, + useSSR, type SharedRsbuildPluginAPI, } from '@rsbuild/shared'; diff --git a/packages/plugin-styled-components/src/index.ts b/packages/plugin-styled-components/src/index.ts index 6b99fd6a9a..092eca6d42 100644 --- a/packages/plugin-styled-components/src/index.ts +++ b/packages/plugin-styled-components/src/index.ts @@ -3,6 +3,7 @@ import { getDefaultStyledComponentsConfig, mergeChainedOptions, ChainedConfig, + useSSR, } from '@rsbuild/shared'; /** @@ -30,7 +31,7 @@ export const pluginStyledComponents = ( api.modifyBundlerChain(async (chain, { CHAIN_ID, isProd, target }) => { const { bundlerType } = api.context; - const isSSR = target === 'node'; + const isSSR = useSSR(api.context.target); const styledComponentsOptions = mergeChainedOptions< StyledComponentsOptions, diff --git a/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap b/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap index 19d1e9b897..98d38bf62a 100644 --- a/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap +++ b/packages/plugin-styled-components/tests/__snapshots__/index.test.ts.snap @@ -1,5 +1,121 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`plugins/styled-components > should enable ssr when target contain node 1`] = ` +{ + "include": [ + { + "and": [ + "", + { + "not": /\\[\\\\\\\\/\\]node_modules\\[\\\\\\\\/\\]/, + }, + ], + }, + ], + "test": /\\\\\\.\\(js\\|mjs\\|cjs\\|jsx\\)\\$\\|\\\\\\.\\(ts\\|mts\\|cts\\|tsx\\)\\$/, + "type": "javascript/auto", + "use": [ + { + "loader": "builtin:swc-loader", + "options": { + "env": { + "targets": [ + "node >= 14", + ], + }, + "exclude": [], + "inlineSourcesContent": true, + "isModule": "unknown", + "jsc": { + "externalHelpers": true, + "parser": { + "decorators": true, + "syntax": "typescript", + "tsx": true, + }, + "transform": { + "decoratorMetadata": true, + "legacyDecorator": true, + }, + }, + "minify": false, + "rspackExperiments": { + "styledComponents": { + "displayName": true, + "pure": false, + "ssr": true, + "transpileTemplateLiterals": true, + }, + }, + "sourceMaps": true, + }, + }, + ], +} +`; + +exports[`plugins/styled-components > should enable ssr when target contain node 2`] = ` +{ + "exclude": [ + "/node_modules//core-js", + ], + "include": [ + { + "and": [ + "", + { + "not": /\\[\\\\\\\\/\\]node_modules\\[\\\\\\\\/\\]/, + }, + ], + }, + ], + "test": /\\\\\\.\\(js\\|mjs\\|cjs\\|jsx\\)\\$\\|\\\\\\.\\(ts\\|mts\\|cts\\|tsx\\)\\$/, + "type": "javascript/auto", + "use": [ + { + "loader": "builtin:swc-loader", + "options": { + "env": { + "coreJs": "3.32", + "mode": "entry", + "targets": [ + "chrome >= 87", + "edge >= 88", + "firefox >= 78", + "safari >= 14", + ], + }, + "exclude": [], + "inlineSourcesContent": true, + "isModule": "unknown", + "jsc": { + "externalHelpers": true, + "parser": { + "decorators": true, + "syntax": "typescript", + "tsx": true, + }, + "transform": { + "decoratorMetadata": true, + "legacyDecorator": true, + }, + }, + "minify": false, + "rspackExperiments": { + "styledComponents": { + "displayName": true, + "pure": false, + "ssr": true, + "transpileTemplateLiterals": true, + }, + }, + "sourceMaps": true, + }, + }, + ], +} +`; + exports[`plugins/styled-components > should works in rspack mode 1`] = ` { "exclude": [ diff --git a/packages/plugin-styled-components/tests/index.test.ts b/packages/plugin-styled-components/tests/index.test.ts index 221c18c0a1..0d4553ac07 100644 --- a/packages/plugin-styled-components/tests/index.test.ts +++ b/packages/plugin-styled-components/tests/index.test.ts @@ -6,6 +6,25 @@ import { webpackProvider } from '@rsbuild/webpack'; import { pluginSwc } from '@rsbuild/plugin-swc'; describe('plugins/styled-components', () => { + it('should enable ssr when target contain node', async () => { + const rsbuild = await createStubRsbuild({ + rsbuildConfig: {}, + target: ['node', 'web'], + }); + + rsbuild.addPlugins([pluginStyledComponents()]); + const configs = await rsbuild.initConfigs(); + + for (const config of configs) { + expect( + config.module.rules.find( + (r) => + r.test.toString() === mergeRegex(JS_REGEX, TS_REGEX).toString(), + ), + ).toMatchSnapshot(); + } + }); + it('should works in rspack mode', async () => { const rsbuild = await createStubRsbuild({ rsbuildConfig: {}, diff --git a/packages/shared/src/utils.ts b/packages/shared/src/utils.ts index ea0fd84ca0..07507c89ec 100644 --- a/packages/shared/src/utils.ts +++ b/packages/shared/src/utils.ts @@ -157,3 +157,9 @@ export const isBeyondReact17 = (cwd: string) => { return semver.satisfies(semver.minVersion(deps.react)!, '>=17.0.0'); }; + +export function useSSR(target: RsbuildTarget | RsbuildTarget[]) { + return (Array.isArray(target) ? target : [target]).some((item) => + ['node', 'service-worker'].includes(item), + ); +}