From 66d1ae6c01cc970904d8cd8589d8ff2d77e27b59 Mon Sep 17 00:00:00 2001 From: neverland Date: Mon, 22 Apr 2024 18:45:32 +0800 Subject: [PATCH] feat: provide type declaration for builtin:swc-loader (#6314) * feat: provide type declaration for builtin:swc-loader * docs: add document * fix: api.md * fix: missing isModule * fix: import type --- packages/rspack/etc/api.md | 133 +++++ .../rspack/src/builtin-loader/swc/index.ts | 11 + .../src/builtin-loader/swc/pluginImport.ts | 6 +- .../rspack/src/builtin-loader/swc/react.ts | 2 +- .../rspack/src/builtin-loader/swc/relay.ts | 3 +- .../rspack/src/builtin-loader/swc/types.ts | 497 ++++++++++++++++++ packages/rspack/src/exports.ts | 12 + website/docs/en/blog/announcing-0.5.mdx | 6 +- website/docs/en/guide/builtin-swc-loader.mdx | 69 ++- website/docs/en/guide/vue.mdx | 2 +- website/docs/zh/blog/announcing-0.5.mdx | 6 +- website/docs/zh/guide/builtin-swc-loader.mdx | 100 +++- website/docs/zh/guide/vue.mdx | 2 +- 13 files changed, 804 insertions(+), 45 deletions(-) create mode 100644 packages/rspack/src/builtin-loader/swc/types.ts diff --git a/packages/rspack/etc/api.md b/packages/rspack/etc/api.md index e20b7786dc2..5cd7ac363e1 100644 --- a/packages/rspack/etc/api.md +++ b/packages/rspack/etc/api.md @@ -59,6 +59,8 @@ import type { RawLibraryOptions } from '@rspack/binding'; import { RawLimitChunkCountPluginOptions } from '@rspack/binding'; import type { RawOptions } from '@rspack/binding'; import { RawProgressPluginOptions } from '@rspack/binding'; +import type { RawReactOptions } from '@rspack/binding'; +import type { RawRelayConfig } from '@rspack/binding'; import { RawSourceMapDevToolPluginOptions } from '@rspack/binding'; import { RawSwcJsMinimizerRspackPluginOptions } from '@rspack/binding'; import { ResolveRequest } from 'enhanced-resolve'; @@ -4889,6 +4891,133 @@ export type SwcJsMinimizerRspackPluginOptions = { include?: MinifyConditions; }; +// @public (undocumented) +export interface SwcLoaderEnvConfig { + bugfixes?: boolean; + coreJs?: string; + // (undocumented) + debug?: boolean; + // (undocumented) + dynamicImport?: boolean; + // (undocumented) + exclude?: string[]; + forceAllTransforms?: boolean; + // (undocumented) + include?: string[]; + // (undocumented) + loose?: boolean; + // (undocumented) + mode?: "usage" | "entry"; + // (undocumented) + path?: string; + // (undocumented) + shippedProposals?: boolean; + skip?: string[]; + // (undocumented) + targets?: any; +} + +// @public (undocumented) +export interface SwcLoaderEsParserConfig { + decorators?: boolean; + decoratorsBeforeExport?: boolean; + exportDefaultFrom?: boolean; + functionBind?: boolean; + importAssertions?: boolean; + jsx?: boolean; + // (undocumented) + syntax: "ecmascript"; +} + +// @public (undocumented) +export interface SwcLoaderJscConfig { + // (undocumented) + baseUrl?: string; + experimental?: { + optimizeHygiene?: boolean; + keepImportAttributes?: boolean; + emitAssertForImportAttributes?: boolean; + cacheRoot?: string; + plugins?: Array<[string, Record]>; + disableBuiltinTransformsForInternalTesting?: boolean; + }; + externalHelpers?: boolean; + keepClassNames?: boolean; + // (undocumented) + loose?: boolean; + parser?: SwcLoaderParserConfig; + // (undocumented) + paths?: { + [from: string]: [string]; + }; + // (undocumented) + preserveAllComments?: boolean; + // Warning: (ae-forgotten-export) The symbol "JscTarget" needs to be exported by the entry point index.d.ts + target?: JscTarget; + // (undocumented) + transform?: SwcLoaderTransformConfig; +} + +// Warning: (ae-forgotten-export) The symbol "Es6Config" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "CommonJsConfig" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "UmdConfig" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "AmdConfig" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "NodeNextConfig" needs to be exported by the entry point index.d.ts +// Warning: (ae-forgotten-export) The symbol "SystemjsConfig" needs to be exported by the entry point index.d.ts +// +// @public (undocumented) +export type SwcLoaderModuleConfig = Es6Config | CommonJsConfig | UmdConfig | AmdConfig | NodeNextConfig | SystemjsConfig; + +// @public (undocumented) +export type SwcLoaderOptions = { + test?: string | string[]; + exclude?: string | string[]; + env?: SwcLoaderEnvConfig; + jsc?: SwcLoaderJscConfig; + module?: SwcLoaderModuleConfig; + minify?: boolean; + sourceMaps?: boolean; + inlineSourcesContent?: boolean; + isModule?: boolean | "unknown"; + rspackExperiments?: { + relay?: RelayOptions; + emotion?: EmotionOptions; + import?: PluginImportOptions; + styledComponents?: StyledComponentsOptions; + }; +}; + +// @public (undocumented) +export type SwcLoaderParserConfig = SwcLoaderTsParserConfig | SwcLoaderEsParserConfig; + +// @public (undocumented) +export interface SwcLoaderTransformConfig { + // Warning: (ae-forgotten-export) The symbol "ConstModulesConfig" needs to be exported by the entry point index.d.ts + // + // (undocumented) + constModules?: ConstModulesConfig; + decoratorMetadata?: boolean; + decoratorVersion?: "2021-12" | "2022-03"; + legacyDecorator?: boolean; + // Warning: (ae-forgotten-export) The symbol "OptimizerConfig" needs to be exported by the entry point index.d.ts + optimizer?: OptimizerConfig; + // Warning: (ae-forgotten-export) The symbol "ReactOptions" needs to be exported by the entry point index.d.ts + react?: ReactOptions; + // (undocumented) + treatConstEnumAsEnum?: boolean; + // (undocumented) + useDefineForClassFields?: boolean; +} + +// @public (undocumented) +export interface SwcLoaderTsParserConfig { + decorators?: boolean; + dynamicImport?: boolean; + // (undocumented) + syntax: "typescript"; + tsx?: boolean; +} + // Warning: (ae-forgotten-export) The symbol "target" needs to be exported by the entry point index.d.ts // // @public (undocumented) @@ -5024,6 +5153,10 @@ export type WorkerPublicPath = z.infer; // dist/NormalModuleFactory.d.ts:9:9 - (ae-forgotten-export) The symbol "ResourceDataWithData" needs to be exported by the entry point index.d.ts // dist/NormalModuleFactory.d.ts:10:9 - (ae-forgotten-export) The symbol "ResolveData" needs to be exported by the entry point index.d.ts // dist/NormalModuleFactory.d.ts:12:9 - (ae-forgotten-export) The symbol "NormalModuleCreateData" needs to be exported by the entry point index.d.ts +// dist/builtin-loader/swc/types.d.ts:457:9 - (ae-forgotten-export) The symbol "RelayOptions" needs to be exported by the entry point index.d.ts +// dist/builtin-loader/swc/types.d.ts:458:9 - (ae-forgotten-export) The symbol "EmotionOptions" needs to be exported by the entry point index.d.ts +// dist/builtin-loader/swc/types.d.ts:459:9 - (ae-forgotten-export) The symbol "PluginImportOptions" needs to be exported by the entry point index.d.ts +// dist/builtin-loader/swc/types.d.ts:460:9 - (ae-forgotten-export) The symbol "StyledComponentsOptions" needs to be exported by the entry point index.d.ts // dist/builtin-plugin/SwcJsMinimizerPlugin.d.ts:40:5 - (ae-forgotten-export) The symbol "ExtractCommentsOptions" needs to be exported by the entry point index.d.ts // dist/builtin-plugin/SwcJsMinimizerPlugin.d.ts:41:5 - (ae-forgotten-export) The symbol "TerserCompressOptions" needs to be exported by the entry point index.d.ts // dist/builtin-plugin/SwcJsMinimizerPlugin.d.ts:42:5 - (ae-forgotten-export) The symbol "TerserMangleOptions" needs to be exported by the entry point index.d.ts diff --git a/packages/rspack/src/builtin-loader/swc/index.ts b/packages/rspack/src/builtin-loader/swc/index.ts index eaa67b59154..b5af988b096 100644 --- a/packages/rspack/src/builtin-loader/swc/index.ts +++ b/packages/rspack/src/builtin-loader/swc/index.ts @@ -9,3 +9,14 @@ export type { RelayOptions } from "./relay"; export { resolvePluginImport } from "./pluginImport"; export type { PluginImportOptions } from "./pluginImport"; + +export type { + SwcLoaderOptions, + SwcLoaderEnvConfig, + SwcLoaderJscConfig, + SwcLoaderModuleConfig, + SwcLoaderParserConfig, + SwcLoaderEsParserConfig, + SwcLoaderTsParserConfig, + SwcLoaderTransformConfig +} from "./types"; diff --git a/packages/rspack/src/builtin-loader/swc/pluginImport.ts b/packages/rspack/src/builtin-loader/swc/pluginImport.ts index fefb38fcb0c..0d4aa4ec8a9 100644 --- a/packages/rspack/src/builtin-loader/swc/pluginImport.ts +++ b/packages/rspack/src/builtin-loader/swc/pluginImport.ts @@ -1,4 +1,4 @@ -import { RawPluginImportConfig } from "@rspack/binding"; +import type { RawPluginImportConfig } from "@rspack/binding"; type PluginImportConfig = { libraryName: string; @@ -9,8 +9,8 @@ type PluginImportConfig = { styleLibraryDirectory?: string; camelToDashComponentName?: boolean; transformToDefaultImport?: boolean; - ignoreEsComponent?: Array; - ignoreStyleComponent?: Array; + ignoreEsComponent?: string[]; + ignoreStyleComponent?: string[]; }; type PluginImportOptions = PluginImportConfig[] | undefined; diff --git a/packages/rspack/src/builtin-loader/swc/react.ts b/packages/rspack/src/builtin-loader/swc/react.ts index c2fd2d176ba..2b02bdb1985 100644 --- a/packages/rspack/src/builtin-loader/swc/react.ts +++ b/packages/rspack/src/builtin-loader/swc/react.ts @@ -1,4 +1,4 @@ -import { RawReactOptions } from "@rspack/binding"; +import type { RawReactOptions } from "@rspack/binding"; function resolveReact(react: ReactOptions): RawReactOptions { return react ?? {}; diff --git a/packages/rspack/src/builtin-loader/swc/relay.ts b/packages/rspack/src/builtin-loader/swc/relay.ts index 7d274c8f8f8..617bee971b2 100644 --- a/packages/rspack/src/builtin-loader/swc/relay.ts +++ b/packages/rspack/src/builtin-loader/swc/relay.ts @@ -1,6 +1,5 @@ import path from "path"; - -import { RawRelayConfig } from "@rspack/binding"; +import type { RawRelayConfig } from "@rspack/binding"; type RelayOptions = boolean | RawRelayConfig | undefined; diff --git a/packages/rspack/src/builtin-loader/swc/types.ts b/packages/rspack/src/builtin-loader/swc/types.ts new file mode 100644 index 00000000000..6dc14d9a0da --- /dev/null +++ b/packages/rspack/src/builtin-loader/swc/types.ts @@ -0,0 +1,497 @@ +/** + * Some types are modified from https://github.com/swc-project/swc/blob/16a38851/packages/types/index.ts#L647 + * license at https://github.com/swc-project/swc/blob/main/LICENSE + */ +import type { ReactOptions } from "./react"; +import type { RelayOptions } from "./relay"; +import type { EmotionOptions } from "./emotion"; +import type { PluginImportOptions } from "./pluginImport"; + +export type StyledComponentsOptions = { + displayName?: boolean; + ssr?: boolean; + fileName?: boolean; + meaninglessFileNames?: string[]; + namespace?: string; + topLevelImportPaths?: string[]; + transpileTemplateLiterals?: boolean; + minify?: boolean; + pure?: boolean; + cssProps?: boolean; +}; + +export type JscTarget = + | "es3" + | "es5" + | "es2015" + | "es2016" + | "es2017" + | "es2018" + | "es2019" + | "es2020" + | "es2021" + | "es2022" + | "esnext"; + +export type SwcLoaderParserConfig = + | SwcLoaderTsParserConfig + | SwcLoaderEsParserConfig; + +export interface SwcLoaderTsParserConfig { + syntax: "typescript"; + /** + * Defaults to `false`. + */ + tsx?: boolean; + /** + * Defaults to `false`. + */ + decorators?: boolean; + /** + * Defaults to `false` + */ + dynamicImport?: boolean; +} + +export interface SwcLoaderEsParserConfig { + syntax: "ecmascript"; + /** + * Defaults to false. + */ + jsx?: boolean; + /** + * Defaults to `false` + */ + functionBind?: boolean; + /** + * Defaults to `false` + */ + decorators?: boolean; + /** + * Defaults to `false` + */ + decoratorsBeforeExport?: boolean; + /** + * Defaults to `false` + */ + exportDefaultFrom?: boolean; + /** + * Defaults to `false` + */ + importAssertions?: boolean; +} + +/** + * - `import { DEBUG } from '@ember/env-flags';` + * - `import { FEATURE_A, FEATURE_B } from '@ember/features';` + * + * See: https://github.com/swc-project/swc/issues/18#issuecomment-466272558 + */ +export type ConstModulesConfig = { + globals?: { + [module: string]: { + [name: string]: string; + }; + }; +}; + +/** + * Options for inline-global pass. + */ +export interface GlobalPassOption { + /** + * Global variables that should be inlined with passed value. + * + * e.g. `{ __DEBUG__: true }` + */ + vars?: Record; + /** + * Names of environment variables that should be inlined with the value of corresponding env during build. + * + * Defaults to `["NODE_ENV", "SWC_ENV"]` + */ + envs?: string[] | Record; + /** + * Replaces typeof calls for passed variables with corresponding value + * + * e.g. `{ window: 'object' }` + */ + typeofs?: Record; +} + +/** + * https://swc.rs/docs/configuring-swc.html#jsctransformoptimizerjsonify + */ +export type OptimizerConfig = { + /** + * https://swc.rs/docs/configuration/compilation#jsctransformoptimizersimplify + */ + simplify?: boolean; + /** + * https://swc.rs/docs/configuring-swc.html#jsctransformoptimizerglobals + */ + globals?: GlobalPassOption; + /** + * https://swc.rs/docs/configuring-swc.html#jsctransformoptimizerjsonify + */ + jsonify?: { minCost: number }; +}; + +export interface SwcLoaderTransformConfig { + /** + * Effective only if `syntax` supports ƒ. + */ + react?: ReactOptions; + constModules?: ConstModulesConfig; + /** + * Defaults to null, which skips optimizer pass. + */ + optimizer?: OptimizerConfig; + /** + * https://swc.rs/docs/configuring-swc.html#jsctransformlegacydecorator + */ + legacyDecorator?: boolean; + /** + * https://swc.rs/docs/configuring-swc.html#jsctransformdecoratormetadata + */ + decoratorMetadata?: boolean; + /** + * https://swc.rs/docs/configuration/compilation#jsctransformdecoratorversion + */ + decoratorVersion?: "2021-12" | "2022-03"; + treatConstEnumAsEnum?: boolean; + useDefineForClassFields?: boolean; +} + +export interface SwcLoaderEnvConfig { + mode?: "usage" | "entry"; + debug?: boolean; + dynamicImport?: boolean; + loose?: boolean; + /** + * Transpiles the broken syntax to the closest non-broken modern syntax + * Defaults to false. + */ + bugfixes?: boolean; + /** + * Skipped es features. + * e.g.) + * - `core-js/modules/foo` + */ + skip?: string[]; + include?: string[]; + exclude?: string[]; + /** + * The version of the used core js. + */ + coreJs?: string; + targets?: any; + path?: string; + shippedProposals?: boolean; + /** + * Enable all transforms + */ + forceAllTransforms?: boolean; +} + +export interface SwcLoaderJscConfig { + loose?: boolean; + /** + * Defaults to EsParserConfig + */ + parser?: SwcLoaderParserConfig; + transform?: SwcLoaderTransformConfig; + /** + * Use `@swc/helpers` instead of inline helpers. + */ + externalHelpers?: boolean; + /** + * Defaults to `es3` (which enabled **all** pass). + */ + target?: JscTarget; + /** + * Keep class names. + */ + keepClassNames?: boolean; + /** + * This is experimental, and can be removed without a major version bump. + */ + experimental?: { + optimizeHygiene?: boolean; + /** + * Preserve `with` in imports and exports. + */ + keepImportAttributes?: boolean; + /** + * Use `assert` instead of `with` for imports and exports. + * This option only works when `keepImportAttributes` is `true`. + */ + emitAssertForImportAttributes?: boolean; + /** + * Specify the location where SWC stores its intermediate cache files. + * Currently only transform plugin uses this. If not specified, SWC will + * create `.swc` directories. + */ + cacheRoot?: string; + /** + * List of custom transform plugins written in WebAssembly. + * First parameter of tuple indicates the name of the plugin - it can be either + * a name of the npm package can be resolved, or absolute path to .wasm binary. + * + * Second parameter of tuple is JSON based configuration for the plugin. + */ + plugins?: Array<[string, Record]>; + /** + * Disable builtin transforms. If enabled, only Wasm plugins are used. + */ + disableBuiltinTransformsForInternalTesting?: boolean; + }; + baseUrl?: string; + paths?: { + [from: string]: [string]; + }; + preserveAllComments?: boolean; +} + +export type SwcLoaderModuleConfig = + | Es6Config + | CommonJsConfig + | UmdConfig + | AmdConfig + | NodeNextConfig + | SystemjsConfig; + +export interface BaseModuleConfig { + /** + * By default, when using exports with babel a non-enumerable `__esModule` + * property is exported. In some cases this property is used to determine + * if the import is the default export or if it contains the default export. + * + * In order to prevent the __esModule property from being exported, you + * can set the strict option to true. + * + * Defaults to `false`. + */ + strict?: boolean; + /** + * Emits 'use strict' directive. + * + * Defaults to `true`. + */ + strictMode?: boolean; + /** + * Changes Babel's compiled import statements to be lazily evaluated when their imported bindings are used for the first time. + * + * This can improve initial load time of your module because evaluating dependencies up + * front is sometimes entirely un-necessary. This is especially the case when implementing + * a library module. + * + * + * The value of `lazy` has a few possible effects: + * + * - `false` - No lazy initialization of any imported module. + * - `true` - Do not lazy-initialize local `./foo` imports, but lazy-init `foo` dependencies. + * + * Local paths are much more likely to have circular dependencies, which may break if loaded lazily, + * so they are not lazy by default, whereas dependencies between independent modules are rarely cyclical. + * + * - `Array` - Lazy-initialize all imports with source matching one of the given strings. + * + * ----- + * + * The two cases where imports can never be lazy are: + * + * - `import "foo";` + * + * Side-effect imports are automatically non-lazy since their very existence means + * that there is no binding to later kick off initialization. + * + * - `export * from "foo"` + * + * Re-exporting all names requires up-front execution because otherwise there is no + * way to know what names need to be exported. + * + * Defaults to `false`. + */ + lazy?: boolean | string[]; + /** + * @deprecated Use the `importInterop` option instead. + * + * By default, when using exports with swc a non-enumerable __esModule property is exported. + * This property is then used to determine if the import is the default export or if + * it contains the default export. + * + * In cases where the auto-unwrapping of default is not needed, you can set the noInterop option + * to true to avoid the usage of the interopRequireDefault helper (shown in inline form above). + * + * Defaults to `false`. + */ + noInterop?: boolean; + /** + * Defaults to `swc`. + * + * CommonJS modules and ECMAScript modules are not fully compatible. + * However, compilers, bundlers and JavaScript runtimes developed different strategies + * to make them work together as well as possible. + * + * - `swc` (alias: `babel`) + * + * When using exports with `swc` a non-enumerable `__esModule` property is exported + * This property is then used to determine if the import is the default export + * or if it contains the default export. + * + * ```javascript + * import foo from "foo"; + * import { bar } from "bar"; + * foo; + * bar; + * + * // Is compiled to ... + * + * "use strict"; + * + * function _interop_require_default(obj) { + * return obj && obj.__esModule ? obj : { default: obj }; + * } + * + * var _foo = _interop_require_default(require("foo")); + * var _bar = require("bar"); + * + * _foo.default; + * _bar.bar; + * ``` + * + * When this import interop is used, if both the imported and the importer module are compiled + * with swc they behave as if none of them was compiled. + * + * This is the default behavior. + * + * - `node` + * + * When importing CommonJS files (either directly written in CommonJS, or generated with a compiler) + * Node.js always binds the `default` export to the value of `module.exports`. + * + * ```javascript + * import foo from "foo"; + * import { bar } from "bar"; + * foo; + * bar; + * + * // Is compiled to ... + * + * "use strict"; + * + * var _foo = require("foo"); + * var _bar = require("bar"); + * + * _foo; + * _bar.bar; + * ``` + * This is not exactly the same as what Node.js does since swc allows accessing any property of `module.exports` + * as a named export, while Node.js only allows importing statically analyzable properties of `module.exports`. + * However, any import working in Node.js will also work when compiled with swc using `importInterop: "node"`. + * + * - `none` + * + * If you know that the imported file has been transformed with a compiler that stores the `default` export on + * `exports.default` (such as swc or Babel), you can safely omit the `_interop_require_default` helper. + * + * ```javascript + * import foo from "foo"; + * import { bar } from "bar"; + * foo; + * bar; + * + * // Is compiled to ... + * + * "use strict"; + * + * var _foo = require("foo"); + * var _bar = require("bar"); + * + * _foo.default; + * _bar.bar; + * ``` + */ + importInterop?: "swc" | "babel" | "node" | "none"; + /** + * Emits `cjs-module-lexer` annotation + * `cjs-module-lexer` is used in Node.js core for detecting the named exports available when importing a CJS module into ESM. + * swc will emit `cjs-module-lexer` detectable annotation with this option enabled. + * + * Defaults to `true` if import_interop is Node, else `false` + */ + exportInteropAnnotation?: boolean; + /** + * If set to true, dynamic imports will be preserved. + */ + ignoreDynamic?: boolean; + allowTopLevelThis?: boolean; + preserveImportMeta?: boolean; +} + +export interface Es6Config extends BaseModuleConfig { + type: "es6"; +} + +export interface NodeNextConfig extends BaseModuleConfig { + type: "nodenext"; +} + +export interface CommonJsConfig extends BaseModuleConfig { + type: "commonjs"; +} + +export interface UmdConfig extends BaseModuleConfig { + type: "umd"; + globals?: { [key: string]: string }; +} + +export interface AmdConfig extends BaseModuleConfig { + type: "amd"; + moduleId?: string; +} + +export interface SystemjsConfig { + type: "systemjs"; + allowTopLevelThis?: boolean; +} + +export type SwcLoaderOptions = { + /** + * Note: The type is string because it follows rust's regex syntax. + */ + test?: string | string[]; + /** + * Note: The type is string because it follows rust's regex syntax. + */ + exclude?: string | string[]; + env?: SwcLoaderEnvConfig; + jsc?: SwcLoaderJscConfig; + module?: SwcLoaderModuleConfig; + minify?: boolean; + /** + * - true to generate a sourcemap for the code and include it in the result object. + * - "inline" to generate a sourcemap and append it as a data URL to the end of the code, but not include it in the result object. + * + * `swc-cli` overloads some of these to also affect how maps are written to disk: + * + * - true will write the map to a .map file on disk + * - "inline" will write the file directly, so it will have a data: containing the map + * - Note: These options are bit weird, so it may make the most sense to just use true + * and handle the rest in your own code, depending on your use case. + */ + sourceMaps?: boolean; + inlineSourcesContent?: boolean; + isModule?: boolean | "unknown"; + /** + * Experimental features provided by Rspack. + * @experimental + */ + rspackExperiments?: { + relay?: RelayOptions; + emotion?: EmotionOptions; + import?: PluginImportOptions; + styledComponents?: StyledComponentsOptions; + }; +}; diff --git a/packages/rspack/src/exports.ts b/packages/rspack/src/exports.ts index 50735366357..e2d0cc2ec99 100644 --- a/packages/rspack/src/exports.ts +++ b/packages/rspack/src/exports.ts @@ -238,3 +238,15 @@ export { EvalDevToolModulePlugin } from "./builtin-plugin"; export type { EvalDevToolModulePluginOptions } from "./builtin-plugin"; export { CssExtractRspackPlugin } from "./builtin-plugin"; + +///// Rspack Postfixed Internal Loaders ///// +export type { + SwcLoaderOptions, + SwcLoaderEnvConfig, + SwcLoaderJscConfig, + SwcLoaderModuleConfig, + SwcLoaderParserConfig, + SwcLoaderEsParserConfig, + SwcLoaderTsParserConfig, + SwcLoaderTransformConfig +} from "./builtin-loader/swc/index"; diff --git a/website/docs/en/blog/announcing-0.5.mdx b/website/docs/en/blog/announcing-0.5.mdx index 9a4a2f2dc05..06af9775aeb 100644 --- a/website/docs/en/blog/announcing-0.5.mdx +++ b/website/docs/en/blog/announcing-0.5.mdx @@ -45,7 +45,7 @@ module.exports = { exclude: /[\\/]node_modules[\\/]/, loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'ecmascript', @@ -70,7 +70,7 @@ module.exports = { exclude: /[\\/]node_modules[\\/]/, loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'typescript', @@ -95,7 +95,7 @@ module.exports = { exclude: /[\\/]node_modules[\\/]/, loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'typescript', diff --git a/website/docs/en/guide/builtin-swc-loader.mdx b/website/docs/en/guide/builtin-swc-loader.mdx index 45c732a7297..6b51169c8f1 100644 --- a/website/docs/en/guide/builtin-swc-loader.mdx +++ b/website/docs/en/guide/builtin-swc-loader.mdx @@ -6,6 +6,8 @@ import { ApiMeta, Stability } from '../../../components/ApiMeta'; `builtin:swc-loader` is the Rust version of [`swc-loader`](https://github.com/swc-project/pkgs/tree/main/packages/swc-loader), aiming to deliver better performance. The Loader's [configuration](https://swc.rs/docs/configuration/compilation) is aligned with the JS version of `swc-loader` (SWC plugins will be provided in future releases and are currently not supported). +## Example + If you need to use `builtin:swc-loader` in your project, configure it as follows: To transpile `ts` files: @@ -19,7 +21,7 @@ module.exports = { exclude: [/node_modules/], loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'typescript', @@ -71,11 +73,60 @@ module.exports = { Additionally, you can directly refer to [`example-builtin-swc-loader`](https://github.com/rspack-contrib/rspack-examples/tree/main/rspack/builtin-swc-loader) for more usage guidelines. -## options +## Type declaration + + + +You can enable type hints using the `SwcLoaderOptions` type exported by `@rspack/core`: + +- `rspack.config.js`: + +```js +module.exports = { + module: { + rules: [ + { + test: /\.js$/, + use: { + loader: 'builtin:swc-loader', + /** @type {import('@rspack/core').SwcLoaderOptions} */ + options: { + // some options + }, + }, + }, + ], + }, +}; +``` + +- `rspack.config.ts`: + +```ts +import type { SwcLoaderOptions } from '@rspack/core'; + +export default { + module: { + rules: [ + { + test: /\.js$/, + use: { + loader: 'builtin:swc-loader', + options: { + // some options + } satisfies SwcLoaderOptions, + }, + }, + ], + }, +}; +``` + +## Options -See [SWC configuration](https://swc.rs/docs/configuration/swcrc). +The following is an introduction to some SWC configurations and Rspack specific configurations. Please refer to the [SWC Configurations](https://swc.rs/docs/configuration/swcrc) for the complete options. -### options.jsc.experimental.plugins +### jsc.experimental.plugins @@ -117,13 +168,13 @@ module.exports = { this is an [example](https://github.com/rspack-contrib/rspack-examples/blob/d4b8aaef9915ed0f540edbe504217c3d1afe8989/rspack/builtin-swc-loader/rspack.config.js#L45) of wasm plugin usage. -### options.rspackExperiments +### rspackExperiments Experimental features provided by rspack. -### options.rspackExperiments.import +### rspackExperiments.import @@ -269,7 +320,7 @@ import Button from 'antd/es/button'; import 'antd/es/button/style'; ``` -### options.rspackExperiments.relay +### rspackExperiments.relay @@ -292,7 +343,7 @@ export type RelayOptions = When this configuration is set to `true`, Rspack will attempt to locate `relay.config.json`, `relay.config.js`, and `package.json` files under the [context](/config/context) directory in order, as detailed in the [relay-compiler](https://github.com/facebook/relay/tree/main/packages/relay-compiler) documentation. If none of these files are found, Rspack will use the default configuration. If specific configuration is passed, Rspack will not attempt to locate any `relay` config file, but use the received configuration directly. -### options.rspackExperiments.emotion +### rspackExperiments.emotion @@ -400,7 +451,7 @@ export type ImportMap = This option allows you to tell Rspack what imports it should look at to determine what it should transform so if you re-export Emotion's exports, you can still use the Babel transforms -### options.rspackExperiments.styledComponents +### rspackExperiments.styledComponents diff --git a/website/docs/en/guide/vue.mdx b/website/docs/en/guide/vue.mdx index 2b6c6ce4b2c..ae0653dfa98 100644 --- a/website/docs/en/guide/vue.mdx +++ b/website/docs/en/guide/vue.mdx @@ -109,7 +109,7 @@ module.exports = { test: /\.ts$/, // add this rule when you use typescript in Vue SFC loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'typescript', diff --git a/website/docs/zh/blog/announcing-0.5.mdx b/website/docs/zh/blog/announcing-0.5.mdx index 2399df82840..f7622dc93ce 100644 --- a/website/docs/zh/blog/announcing-0.5.mdx +++ b/website/docs/zh/blog/announcing-0.5.mdx @@ -45,7 +45,7 @@ module.exports = { exclude: /[\\/]node_modules[\\/]/, loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'ecmascript', @@ -70,7 +70,7 @@ module.exports = { exclude: /[\\/]node_modules[\\/]/, loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'typescript', @@ -95,7 +95,7 @@ module.exports = { exclude: /[\\/]node_modules[\\/]/, loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'typescript', diff --git a/website/docs/zh/guide/builtin-swc-loader.mdx b/website/docs/zh/guide/builtin-swc-loader.mdx index bb00369634c..fa9b46e4691 100644 --- a/website/docs/zh/guide/builtin-swc-loader.mdx +++ b/website/docs/zh/guide/builtin-swc-loader.mdx @@ -7,9 +7,11 @@ import { ApiMeta, Stability } from '../../../components/ApiMeta'; `builtin:swc-loader` 是 [`swc-loader`](https://github.com/swc-project/pkgs/tree/main/packages/swc-loader) 的 Rust 版本,旨在提供更优的性能, Loader 的[配置](https://swc.rs/docs/configuration/compilation)与 JS 版本的 `swc-loader` 保持对齐(SWC 插件将会在未来版本进行提供,暂不支持)。 -如需要在项目中使用 `builtin:swc-loader`,需进行如下配置。 +## 示例 -如对 `ts` 文件进行转译: +如果需要在项目中使用 `builtin:swc-loader`,需进行如下配置。 + +比如对 `ts` 文件进行转译: ```js module.exports = { @@ -20,7 +22,7 @@ module.exports = { exclude: [/node_modules/], loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'typescript', @@ -34,31 +36,36 @@ module.exports = { }; ``` -或是对 `jsx` 文件进行转译: +或是对 `js` 文件进行转译: ```js module.exports = { module: { rules: [ { - test: /\.js$/, + test: /\.jsx$/, use: { loader: 'builtin:swc-loader', options: { + sourceMap: true, jsc: { - experimental: { - plugins: [ - [ - '@swc/plugin-remove-console', - { - exclude: ['error'], - }, - ], - ], + parser: { + syntax: 'ecmascript', + jsx: true, + }, + transform: { + react: { + pragma: 'React.createElement', + pragmaFrag: 'React.Fragment', + throwIfNamespace: true, + development: false, + useBuiltins: false, + }, }, }, }, }, + type: 'javascript/auto', }, ], }, @@ -67,11 +74,60 @@ module.exports = { 另外,你也可以直接参考 [`example-builtin-swc-loader`](https://github.com/rspack-contrib/rspack-examples/tree/main/rspack/builtin-swc-loader) 查看更多使用指南。 -## options +## 类型声明 + + + +你可以使用 `@rspack/core` 导出的 `SwcLoaderOptions` 类型来开启类型提示: + +- `rspack.config.js`: + +```js +module.exports = { + module: { + rules: [ + { + test: /\.js$/, + use: { + loader: 'builtin:swc-loader', + /** @type {import('@rspack/core').SwcLoaderOptions} */ + options: { + // some options + }, + }, + }, + ], + }, +}; +``` + +- `rspack.config.ts`: + +```ts +import type { SwcLoaderOptions } from '@rspack/core'; + +export default { + module: { + rules: [ + { + test: /\.js$/, + use: { + loader: 'builtin:swc-loader', + options: { + // some options + } satisfies SwcLoaderOptions, + }, + }, + ], + }, +}; +``` + +## Options -参考 [SWC 配置](https://swc.rs/docs/configuration/swcrc)。 +下面是部分 SWC 配置以及 Rspack 特有配置的介绍,完整选项请参考 [SWC 配置](https://swc.rs/docs/configuration/swcrc)。 -### options.jsc.experimental.plugins +### jsc.experimental.plugins @@ -110,11 +166,11 @@ Rspack 支持在 `builtin:swc-loader` 里加载 `swc` 的 `wasm` 插件, 你可 这是 wasm 插件的一个[示例](https://github.com/rspack-contrib/rspack-examples/blob/d4b8aaef9915ed0f540edbe504217c3d1afe8989/rspack/builtin-swc-loader/rspack.config.js#L45)。 -### options.rspackExperiments +### rspackExperiments Rspack 内置的实验性功能。 -### options.rspackExperiments.import +### rspackExperiments.import @@ -262,7 +318,7 @@ import Button from 'antd/es/button'; import 'antd/es/button/style'; ``` -### options.rspackExperiments.relay +### rspackExperiments.relay @@ -285,7 +341,7 @@ type RelayOptions = 当该配置为 `true` 时,Rspack 会从依次尝试寻找 [context](/config/context) 目录下的 `relay.config.json`,`relay.config.js` 以及 `package.json`,详情可以参考 [relay-compiler](https://github.com/facebook/relay/tree/main/packages/relay-compiler) 文档,如果没找到则会使用默认配置。 如果传入具体的配置则不会尝试查找任何 `relay` 配置文件,而是直接使用传入的配置。 -### options.rspackExperiments.emotion +### rspackExperiments.emotion @@ -393,7 +449,7 @@ export type ImportMap = 此选项允许你告诉 Rspack 它应该查看哪些 import 语句,确定应该转换什么,因此如果你重导出 emotion 的方法,仍然可以转换。 -### options.rspackExperiments.styledComponents +### rspackExperiments.styledComponents diff --git a/website/docs/zh/guide/vue.mdx b/website/docs/zh/guide/vue.mdx index c6b8bed3b9e..a194600d0a9 100644 --- a/website/docs/zh/guide/vue.mdx +++ b/website/docs/zh/guide/vue.mdx @@ -109,7 +109,7 @@ module.exports = { test: /\.ts$/, // 如果需要在 Vue SFC 里使用 TypeScript, 请添加该规则 loader: 'builtin:swc-loader', options: { - sourceMap: true, + sourceMaps: true, jsc: { parser: { syntax: 'typescript',