話說最近本來在倒騰 Prisma 和 Graphql ,可是用 vite 做一個前端示例的時候,偏偏被一個蛋疼的問題卡住了,不得已只好重新用 webpack ,正好試試 SWC。
嚴格論,SWC 是 babel 的取代者,等量對比的應該是 SWC vs esbuild。
SWC
Rust-based platform for the Web
SWC 是一個可擴展的基於 Rust 的平臺,適用於下一代快速開發工具。 它被 Next.js、Parcel 和 Deno 等工具以及 Vercel、ByteDance、騰訊、Shopify 等公司使用。
SWC 可用於編譯和捆綁。 對於編譯,它使用現代 JavaScript 功能獲取 JavaScript / TypeScript 文件,並輸出所有主流瀏覽器都支持的有效代碼。
.swcrc 編譯配置
SWC 開箱即用,無需定製。 或者,您可以覆蓋配置。 以下是默認值:
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": false,
"dynamicImport": false,
"privateMethod": false,
"functionBind": false,
"exportDefaultFrom": false,
"exportNamespaceFrom": false,
"decorators": false,
"decoratorsBeforeExport": false,
"topLevelAwait": false,
"importMeta": false
},
"transform": null,
"target": "es5",
"loose": false,
"externalHelpers": false,
// Requires v1.2.50 or upper and requires target to be es2016 or upper.
"keepClassNames": false
}
}
jsc.externalHelpers
{
"jsc": {
"externalHelpers": true
}
}
輸出代碼可能依賴於輔助函數來支持目標環境。 默認情況下,輔助函數會內聯到需要的輸出文件中。
您可以通過啓用 externalHelpers
來使用來自外部模塊的幫助程序,幫助程序代碼將由來自 node_modules/@swc/helpers
的輸出文件導入。
捆綁時,此選項將大大減少您的文件大小。
除了 @swc/core
之外,您還必須添加 @swc/helpers
作爲依賴項。
jsc.parser
typescript
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": false,
"dynamicImport": false
}
}
}
ecmascript
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": false,
"dynamicImport": false,
"privateMethod": false,
"functionBind": false,
"classPrivateProperty": false,
"exportDefaultFrom": false,
"exportNamespaceFrom": false,
"decorators": false,
"decoratorsBeforeExport": false,
"importMeta": false
}
}
}
jsc.target
Starting from @swc/core
v1.0.27, you can specify the target environment by using the field.
{
"jsc": {
// Disable es3 / es5 / es2015 transforms
"target": "es2016"
}
}
jsc.loose
Starting from @swc/core
v1.1.4, you can enable "loose" transformations by enabling jsc.loose
which works like babel-preset-env
loose mode.
{
"jsc": {
"loose": true
}
}
參考:Babel 6: loose mode (2ality.com)
ES Class 代碼
class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return `(${this.x}, ${this.y})`; } }
正常模式
"use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); // (A) } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Point = (function () { function Point(x, y) { _classCallCheck(this, Point); this.x = x; this.y = y; } _createClass(Point, [{ key: "toString", value: function toString() { return "(" + this.x + ", " + this.y + ")"; } }]); return Point; })();
Loose 模式
"use strict"; function _classCallCheck(instance, Constructor) { ··· } var Point = (function () { function Point(x, y) { _classCallCheck(this, Point); this.x = x; this.y = y; } Point.prototype.toString = function toString() { // (A) return "(" + this.x + ", " + this.y + ")"; }; return Point; })();
jsc.transform
{
"jsc": {
"transform": {
"react": {
"pragma": "React.createElement",
"pragmaFrag": "React.Fragment",
"throwIfNamespace": true,
"development": false,
"useBuiltins": false
},
"optimizer": {
"globals": {
"vars": {
"__DEBUG__": "true"
}
}
}
}
}
}
jsc.transform.legacyDecorator
You can use the legacy (stage 1) class decorators syntax and behavior.
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"decorators": true
},
"transform": {
"legacyDecorator": true
}
}
}
jsc.transform.decoratorMetadata
This feature requires v1.2.13+
.
If you are using typescript and decorators with emitDecoratorMetadata
enabled, you can use swc
for faster iteration:
{
"jsc": {
"parser": {
"syntax": "typescript",
"decorators": true
},
"transform": {
"legacyDecorator": true,
"decoratorMetadata": true
}
}
}
jsc.transform.react
jsc.transform.react.runtime
可能的值: automatic
, classic
. 這會影響 JSX 源代碼的編譯方式。
- Use
runtime: automatic
to use a JSX runtime module (e.g.react/jsx-runtime
introduced in React 17). - Use
runtime: classic
to useReact.createElement
instead - with this option, you must ensure thatReact
is in scope when using JSX.
jsc.transform.react.importSource
- Defaults to
react
. - When using
runtime: automatic
, determines the runtime library to import. - This option can be overrided with
@jsxImportSource foo
.
jsc.transform.react.pragma
- Defaults to
React.createElement
. - When using
runtime: classic
, replaces the function used when compiling JSX expressions. - This option can be overrided with
@jsx foo
.
jsc.transform.react.pragmaFrag
- Defaults to
React.Fragment
- Replace the component used when compiling JSX fragments.
- This option can be overrided with
@jsxFrag foo
.
jsc.transform.react.throwIfNamespace
Toggles whether or not to throw an error if an XML namespaced tag name is used. For example: <f:image />
Though the JSX spec allows this, it is disabled by default since React's JSX does not currently have support for it.
jsc.transform.react.development
Toggles debug props __self
and __source
on elements generated from JSX, which are used by development tooling such as React Developer Tools.
This option is set automatically based on the Webpack mode
setting when used with swc-loader
. See Using swc with webpack.
jsc.transform.react.useBuiltins
Use Object.assign()
instead of _extends
. Defaults to false.
jsc.transform.react.refresh
Enable react-refresh related transform. Defaults to false
as it's considered experimental.
Pass refresh: true
to enable this feature, or an object with the following:
interface ReactRefreshConfig {
refreshReg: String;
refreshSig: String;
emitFullSignatures: boolean;
}
jsc.transform.constModules
{
"jsc": {
"transform": {
"constModules": {
"globals": {
"@ember/env-flags": {
"DEBUG": "true"
},
"@ember/features": {
"FEATURE_A": "false",
"FEATURE_B": "true"
}
}
}
}
}
}
Then, source code like:
import { DEBUG } from "@ember/env-flags";
import { FEATURE_A, FEATURE_B } from "@ember/features";
console.log(DEBUG, FEATURE_A, FEATURE_B);
is transformed to:
console.log(true, false, true);
jsc.transform.optimizer
SWC 優化器假設:
- 它是一個模塊或包裝在一個 iife 中。
- 訪問(獲取)全局變量沒有副作用。 它與 google 閉包編譯器的假設相同。
- You don't add fields to literals like a numeric literal, regular expression or a string literal.
- 文件以 gzip 格式提供。
SWC 不會專注於減少非 gzip 壓縮文件的大小。
將此設置爲 undefined
會跳過優化器通道。
jsc.transform.optimizer.simplify
Requires
v1.2.101+
您可以將其設置爲 false
以在跳過優化時使用 inline_globals
。
{
"jsc": {
"transform": {
"optimizer": {
"simplify": false,
"globals": {
"vars": {
"__DEBUG__": "true"
}
}
}
}
}
}
jsc.transform.optimizer.globals
Requires
v1.2.101+
vars
- Variables to inline.typeofs
- If you set{ "window": "object" }
,typeof window
will be replaced with"object"
.
{
"jsc": {
"transform": {
"optimizer": {
"globals": {
"vars": {
"__DEBUG__": "true"
}
}
}
}
}
}
Then, you can use it like npx swc '__DEBUG__' --filename input.js
.
jsc.transform.optimizer.jsonify
Requires
v1.1.1+
minCost
- 如果解析純對象文字的成本大於此值,則將對象文字轉換爲JSON.parse('{"foo": "bar"}')
。 默認爲 1024。
{
"jsc": {
"transform": {
"optimizer": {
"jsonify": {
"minCost": 0
}
}
}
}
}
This will change all pure object literals to JSON.parse("")
.
jsc.keepClassNames
Requires
v1.2.50+
and target to be es2016 or higher
啓用此選項將使 swc 保留原始類名。
jsc.paths
Requires
v1.2.62+
語法與 tsconfig.json
相同:瞭解更多。
Requires jsc.baseUrl
. See below.
jsc.baseUrl
原文:TypeScript: Documentation - Module Resolution (typescriptlang.org)
Base URL
Using a
baseUrl
is a common practice in applications using AMD module loaders where modules are “deployed” to a single folder at run-time. The sources of these modules can live in different directories, but a build script will put them all together.Setting
baseUrl
informs the compiler where to find modules. All module imports with non-relative names are assumed to be relative to thebaseUrl
.Value of baseUrl is determined as either:
- value of baseUrl command line argument (if given path is relative, it is computed based on current directory)
- value of baseUrl property in ‘tsconfig.json’ (if given path is relative, it is computed based on the location of ‘tsconfig.json’)
Note that relative module imports are not impacted by setting the baseUrl, as they are always resolved relative to their importing files.
You can find more documentation on baseUrl in RequireJS and SystemJS documentation.
Path mapping
Sometimes modules are not directly located under baseUrl. For instance, an import to a module
"jquery"
would be translated at runtime to"node_modules/jquery/dist/jquery.slim.min.js"
. Loaders use a mapping configuration to map module names to files at run-time, see RequireJs documentation and SystemJS documentation.The TypeScript compiler supports the declaration of such mappings using
paths
property intsconfig.json
files. Here is an example for how to specify thepaths
property forjquery
.{ "compilerOptions": { "baseUrl": ".", // This must be specified if "paths" is. "paths": { "jquery": ["node_modules/jquery/dist/jquery"] // This mapping is relative to "baseUrl" } } }
Please notice that
paths
are resolved relative tobaseUrl
. When settingbaseUrl
to another value than"."
, i.e. the directory oftsconfig.json
, the mappings must be changed accordingly. Say, you set"baseUrl": "./src"
in the above example, then jquery should be mapped to"../node_modules/jquery/dist/jquery"
.Using
paths
also allows for more sophisticated mappings including multiple fall back locations. Consider a project configuration where only some modules are available in one location, and the rest are in another. A build step would put them all together in one place. The project layout may look like:projectRoot ├── folder1 │ ├── file1.ts (imports 'folder1/file2' and 'folder2/file3') │ └── file2.ts ├── generated │ ├── folder1 │ └── folder2 │ └── file3.ts └── tsconfig.json
The corresponding
tsconfig.json
would look like:{ "compilerOptions": { "baseUrl": ".", "paths": { "*": ["*", "generated/*"] } } }
This tells the compiler for any module import that matches the pattern
"*"
(i.e. all values), to look in two locations:
"*"
: meaning the same name unchanged, so map<moduleName>
=><baseUrl>/<moduleName>
"generated/*"
meaning the module name with an appended prefix “generated”, so map<moduleName>
=><baseUrl>/generated/<moduleName>
Following this logic, the compiler will attempt to resolve the two imports as such:
import ‘folder1/file2’:
- pattern ’*’ is matched and wildcard captures the whole module name
- try first substitution in the list: ’*’ ->
folder1/file2
- result of substitution is non-relative name - combine it with baseUrl ->
projectRoot/folder1/file2.ts
.- File exists. Done.
import ‘folder2/file3’:
- pattern ’*’ is matched and wildcard captures the whole module name
- try first substitution in the list: ’*’ ->
folder2/file3
- result of substitution is non-relative name - combine it with baseUrl ->
projectRoot/folder2/file3.ts
.- File does not exist, move to the second substitution
- second substitution ‘generated/*’ ->
generated/folder2/file3
- result of substitution is non-relative name - combine it with baseUrl ->
projectRoot/generated/folder2/file3.ts
.- File exists. Done.
jsc.minify
Requires
v1.2.67+
See the documentation for minification for more details.
原文:TypeScript: Documentation - Module Resolution (typescriptlang.org)
Minification
🚧
This feature is still under construction. We are working on making the smallest bundle size possible, without breaking changes.
Starting with
v1.2.67
, you can configure SWC to minify your code by enablingminify
in your.swcrc
file:{ // Enable minification "minify": true, // Optional, configure minifcation options "jsc": { "minify": { "compress": { "unused": true }, "mangle": true } } }
Configuration
jsc.minify.compress
Type:
boolean | object
.Similar to the compress option of
terser
.{ "jsc": { "minify": { "compress": true // equivalent to {} } } }
arguments
, defaults tofalse
.arrows
, defaults totrue
.booleans
, defaults totrue
.booleans_as_integers
, defaults tofalse
.collapse_vars
, defaults totrue
.comparisons
, defaults totrue
.computed_props
, defaults tofalse
.conditionals
, defaults tofalse
.dead_code
, defaults tofalse
.defaults
, defaults totrue
.directives
, defaults tofalse
.drop_console
, defaults tofalse
.drop_debugger
, defaults totrue
.ecma
, defaults to5
.evaluate
, defaults totrue
.global_defs
, defaults to{}
.hoist_funs
, defaults tofalse
.hoist_props
, defaults totrue
.hoist_vars
, defaults tofalse
.ie8
, Ignored.if_return
, defaults totrue
.inline
, defaults to ``.join_vars
, defaults totrue
.keep_classnames
, defaults tofalse
.keep_fargs
, defaults tofalse
.keep_infinity
, defaults tofalse
.loops
, defaults totrue
.negate_iife
, defaults totrue
.passes
, defaults to0
, which means no limit.properties
, defaults totrue
.pure_getters
, defaults to ``.pure_funcs
, defaults to[]
. Type is an array of string.reduce_funcs
, defaults tofalse
.reduce_vars
, defaults tofalse
.sequences
, defaults totrue
.side_effects
, defaults totrue
.switches
, defaults tofalse
.top_retain
, defaults to ``.toplevel
, defaults to ``.typeofs
, defaults totrue
.unsafe
, defaults tofalse
.unsafe_arrows
, defaults tofalse
.unsafe_comps
, defaults tofalse
.unsafe_Function
, defaults tofalse
.unsafe_math
, defaults tofalse
.unsafe_symbols
, defaults tofalse
.unsafe_methods
, defaults tofalse
.unsafe_proto
, defaults tofalse
.unsafe_regexp
, defaults tofalse
.unsafe_undefined
, defaults tofalse
.unused
, defaults totrue
.module
, Ignored. Currently, all files are treated as module.
jsc.minify.mangle
Type:
boolean | object
.Similar to the mangle option of
terser
.{ "jsc": { "minify": { "mangle": true // equivalent to {} } } }
properties
, Defaults tofalse
, andtrue
is identical to{}
.topLevel
, Defaults tofalse
. Aliased astoplevel
for compatibility withterser
.keepClassnames
, Defaults tofalse
. Aliased askeep_classnames
for compatibility withterser
.keepFnames
, Defaults tofalse
.keepPrivateProps
, Defaults tofalse
. Aliased askeep_private_props
for compatibility withterser
.reserved
, Defaults to[]
ie8
, Ignored.safari10
, Not implemented yet.@swc/core Usage
swc.minify(code, options)
This API is asynchronous and all of parsing, minification, and code generation will be done in background thread. The
options
argument is same asjsc.minify
object. For example:import swc from "@swc/core"; const { code, map } = await swc.minify( "import foo from '@src/app'; console.log(foo)", { compress: false, mangle: true, } ); expect(code).toMatchInlineSnapshot(`"import a from'@src/app';console.log(a);"`);
Returns
Promise<{ code: string, map: string }>
.swc.minifySync(code, options)
This API exists on
@swc/core
,@swc/wasm
,@swc/wasm-web
.import swc from "@swc/core"; const { code, map } = swc.minifySync( "import foo from '@src/app'; console.log(foo)", { compress: false, mangle: true, } ); expect(code).toMatchInlineSnapshot(`"import a from'@src/app';console.log(a);"`);
Returns
{ code: string, map: string }
.APIs for WebAssembly
Replacing Terser
您可以通過 yarn resolutions 減少構建時間並覆蓋 Terser,而無需庫來更新它們的依賴項。 示例
package.json
將包括:{ "resolutions": { "terser": "npm:@swc/core" } }
這將對所有嵌套依賴項使用 SWC 縮小器而不是 Terser。 確保刪除鎖定文件並重新安裝依賴項。
$ rm -rf node_modules yarn.lock $ yarn
jsc.experimental
Currently, there are no experimental options.
多個入口
Requires
v1.0.47+
[
{
"test": ".*.js$",
"module": {
"type": "commonjs"
}
},
{
"test": ".*.ts$",
"module": {
"type": "amd"
}
}
]
這使得 SWC 將 JavaScript 文件編譯爲 CommonJS 模塊,並將 TypeScript 文件編譯爲 AMD 模塊。
請注意,test
選項只能用於轉編譯 typescript 文件,例如
{
"test": ".*.ts$",
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true,
"dynamicImport": true
}
}
}
test
Type: Regex / Regex[]
{
"test": ".*.ts$",
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true,
"dynamicImport": true
}
}
}
exclude
Type: Regex / Regex[]
{
"exclude": [".*.js$", ".*.map$"],
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false,
"decorators": true,
"dynamicImport": true
}
}
}
sourceMaps
Requires
v1.2.50+
Enable source map by adding sourceMaps: true
or sourceMaps: 'inline'
to the .swcrc
.
{
"sourceMaps": true
}
inlineSourcesContent
Requires
v1.2.101+
默認爲 true
。 如果要讓 swc
將文件內容存儲到 sourcemap 中,可以將 inlineSourcesContent
設置爲 true
。
{
"sourceMaps": true,
"inlineSourcesContent": true
}
瀏覽器支持
從 v1.1.10
開始,您現在可以使用 browserslist
自動配置支持的瀏覽器。
Usage
First, install browserslist
. Then, update your .swcrc
:
{
"env": {
"targets": {
"chrome": "79"
},
"mode": "entry",
"coreJs": 3
}
}
Options
browserslist
If you want to use browserlists with SWC, omit targets
in your .swcrc
:
{
"env": {
"coreJs": 3
}
}
browserlists
can be configured in multiple ways:
.browserslistrc
browserslist
field in package.json
You can use path to specify a custom path to load these configuration files.
targets
string | Array<string> | { [string]: string }
, defaults to {}
.
Describes the environments you support/target for your project. This can either be a browserslist-compatible query:
{
"env": {
"targets": "> 0.25%, not dead"
}
}
Or an object of minimum environment versions to support:
{
"env": {
"targets": {
"chrome": "58",
"ie": "11"
}
}
}
Example environments:
chrome
opera
edge
firefox
safari
ie
ios
android
node
electron
If targets
is not specified, SWC uses browserslist
to get target information.
path
string
, defaults to current directory.path
specifies the directory to load thebrowserslist
module and any browserslist configuration files. For example,.browserslistrc
orbrowserslist
field in package.json. This can be useful if your build system isn't in the root of your project.
mode
string
, defaults toundefined
.- Possible values:
usage
,entry
,undefined
(this matchesuseBuiltIns
from Babel)
⚠️ The usage
mode is currently not as efficient as Babel, yet.
skip
Define ES features to skip to reduce bundle size. For example, your .swcrc
could be:
{
"env": {
"skip": ["core-js/modules/foo"]
}
}
Additional Options
debug
: (boolean) defaults tofalse
.dynamicImport
: (boolean) defaults tofalse
.loose
: (boolean) defaults tofalse
. Enable loose transformations for any plugins that allow them.include
: (string[]) can be acore-js
module (es.math.sign
) or an SWC pass (transform-spread
).exclude
: (string[]) can be acore-js
module (es.math.sign
) or an SWC pass (transform-spread
).coreJs
: (string) defaults toundefined
. The version ofcore-js
to use.shippedProposals
: (boolean) defaults tofalse
.forceAllTransforms
: (boolean) defaults tofalse
. Enable all possible transforms.
Modules
SWC can transpile your code using ES Modules to CommonJS or UMD/AMD. By default, module statements will remain untouched.
CommonJS
To emit a CommonJS module, change the type
in .swcrc
:
{
"module": {
"type": "commonjs",
// These are defaults.
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false
}
}
ES6
To emit a ES6 module, change the type
in .swcrc
:
{
"module": {
"type": "es6",
// These are defaults.
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false
}
}
AMD
To emit an AMD module, change the type
in .swcrc
:
{
"module": {
"type": "amd",
// Optional. If specified, swc emits named AMD module.
"moduleId": "foo",
// These are defaults.
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false
}
}
UMD
To emit an UMD module, change the type
in .swcrc
:
{
"module": {
"type": "umd",
"globals": {},
// These are defaults.
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false
}
}
Shared Options
These options are shared by commonjs
/ es6
/ umd
/ amd
inside .swcrc
:
{
"module": {
// You can specify "commonjs", "es6", "amd", "umd"
"type": "commonjs",
"strict": false,
"strictMode": true,
"lazy": false,
"noInterop": false,
"ignoreDynamic": false
}
}
strict
默認爲false
。 默認情況下,當使用 SWC 導出時,會導出不可枚舉的 __esModule
屬性。 在某些情況下,此屬性用於確定導入是默認導出還是包含默認導出。默認爲“假”。 默認情況下,當使用 SWC 導出時,會導出不可枚舉的 __esModule
屬性。 在某些情況下,此屬性用於確定導入是默認導出還是包含默認導出。
要防止 __esModule
屬性被導出,您可以將 strict 選項設置爲 true
。
strictMode
Defaults to true
. If true, swc emits 'use strict' directive.
lazy
默認爲“假”。 此選項將 Babel 編譯的 import
語句更改爲在首次使用導入的綁定時進行延遲評估。 這可以改善模塊的初始加載時間,因爲有時完全不需要預先評估依賴項。 在實現庫模塊時尤其如此。
lazy
的值有幾個可能的影響:
false
- 沒有任何導入模塊的延遲初始化。true
- 不要惰性初始化本地./foo
導入,而是惰性初始化foo
依賴項。 本地路徑更可能具有循環依賴,如果延遲加載可能會中斷,因此默認情況下它們不是惰性的,而獨立模塊之間的依賴很少是循環的。Array<string>
- 使用與給定字符串之一匹配的源來延遲初始化所有導入。
導入永遠不會惰性的兩種情況是:
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.
noInterop
默認爲false
。 默認情況下,當使用帶有 swc 的導出時,會導出一個不可枚舉的 __esModule 屬性。 然後,此屬性用於確定導入是默認導出還是包含默認導出。
在不需要自動展開默認值的情況下,您可以將 noInterop 選項設置爲 true 以避免使用 interopRequireDefault 幫助器(如上面的內聯形式所示)。
ignoreDynamic
如果設置爲 true
,將保留動態導入。
打包配置
🚧 此功能仍在建設中。
SWC 能夠將多個 JavaScript 或 TypeScript 文件捆綁爲一個。
此功能當前命名爲 spack
,但在 v2
中將重命名爲 swcpack
。 spack.config.js
將被 swcpack.config.js
棄用。
查看 打包的基本示例。
Configuration
You can configure bundling using spack.config.js
with similar options to webpack. In the future, we are exploring a webpack compatible plugin system.
// spack.config.js
module.exports = {
entry: {
web: __dirname + "/src/index.ts",
},
output: {
path: __dirname + "/lib",
},
};
Note: CommonJS is currently required. In the future, ES Modules will be supported.
如果您想要自動完成或類型檢查配置,您可以使用來自 @swc/core/spack
的 config
函數包裝導出。 這是一個帶有類型註釋的標識函數。
const { config } = require("@swc/core/spack");
module.exports = config({
entry: {
web: __dirname + "/src/index.ts",
},
output: {
path: __dirname + "/lib",
},
});
mode
Possible values: production
, debug
, none
.
Currently this value is not used, but it will behave similarly to webpack.
entry
確定打包的入口。 您可以指定一個文件或包名稱到文件路徑的映射。
注意:目前這應該是絕對路徑。 您可以使用
__dirname
創建一個。未來,SWC 將支持使用相對路徑,並將解析相對於
spack.config.js
的文件。
output
You can change destination directory of the bundler using output
.
const { config } = require("@swc/core/spack");
module.exports = config({
output: {
path: __dirname + "/lib",
// Name is optional.
name: "index.js",
},
});
options
Used to control the behavior of SWC. This field is optional.
Migrating from Babel
SWC 的 編譯 旨在支持所有 ECMAScript 功能。 SWC CLI 旨在替代 Babel:
$ npx babel # old
$ npx swc # new
Babel 也快有 10 年的歷史了,終於也快到他壽終正寢的時候了 —— 他可能沒有死,但是在用戶的心中已經死了。人們早就翹首期盼着類似 SWC 這樣的產物出現。
只是從今天的情況看,SWC 恐怕很難能撐過下一個 10 年(但願回來打臉)。且不說眼下還有 deno wasmer 這些奇行種的存在。
Comparison
This table outlines the differences between SWC and Babel.
babel package name | swc |
---|---|
babel-plugin-external-helpers | ✔️ |
babel-plugin-proposal-async-generator-functions | ✔️ |
babel-plugin-proposal-class-properties | ✔️ |
babel-plugin-proposal-decorators | ✔️ |
babel-plugin-proposal-do-expressions | ❌ (stage 1) |
babel-plugin-proposal-dynamic-import | ✔️ |
babel-plugin-proposal-export-default-from | ✔️ |
babel-plugin-proposal-export-namespace-from | ✔️ |
babel-plugin-proposal-function-bind | ❌ (stage 0) |
babel-plugin-proposal-function-sent | ❌ (stage 2) |
babel-plugin-proposal-json-strings | ✔️ |
babel-plugin-proposal-logical-assignment-operators | ❌ (stage 1) |
babel-plugin-proposal-nullish-coalescing-operator | ✔️ |
babel-plugin-proposal-numeric-separator | ✔️ |
babel-plugin-proposal-object-rest-spread | ✔️ |
babel-plugin-proposal-optional-catch-binding | ✔️ |
babel-plugin-proposal-optional-chaining | ✔️ |
babel-plugin-proposal-partial-application | ❌ (stage 1) |
babel-plugin-proposal-pipeline-operator | ❌ (stage 0) |
babel-plugin-proposal-private-methods | ✔️ |
babel-plugin-proposal-throw-expressions | ❌ (stage 2) |
babel-plugin-proposal-unicode-property-regex | ❌ |
babel-plugin-syntax-async-generators | ✔️ |
babel-plugin-syntax-bigint | ✔️ |
babel-plugin-syntax-class-properties | ✔️ |
babel-plugin-syntax-decorators | ✔️ |
babel-plugin-syntax-do-expressions | ❌ (stage 1) |
babel-plugin-syntax-dynamic-import | ✔️ |
babel-plugin-syntax-export-default-from | ✔️ |
babel-plugin-syntax-export-namespace-from | ✔️ |
babel-plugin-syntax-flow | ❌ |
babel-plugin-syntax-function-bind | ❌ (stage 0) |
babel-plugin-syntax-function-sent | ❌ (stage 2) |
babel-plugin-syntax-import-meta | ❌ (stage 3, wip) |
babel-plugin-syntax-json-strings | ✔️ |
babel-plugin-syntax-jsx | ✔️ |
babel-plugin-syntax-logical-assignment-operators | ❌ (stage 1) |
babel-plugin-syntax-nullish-coalescing-operator | ✔️ |
babel-plugin-syntax-numeric-separator | ✔️ |
babel-plugin-syntax-object-rest-spread | ✔️ |
babel-plugin-syntax-optional-catch-binding | ✔️ |
babel-plugin-syntax-optional-chaining | ✔️ |
babel-plugin-syntax-partial-application | ❌ (stage 1) |
babel-plugin-syntax-pipeline-operator | ❌ (stage 0) |
babel-plugin-syntax-throw-expressions | ❌ (stage 2) |
babel-plugin-syntax-top-level-await | ✔️ |
babel-plugin-syntax-typescript | ✔️ |
babel-plugin-transform-arrow-functions | ✔️ |
babel-plugin-transform-async-to-generator | ✔️ |
babel-plugin-transform-block-scoped-functions | ✔️ |
babel-plugin-transform-block-scoping | ✔️ |
babel-plugin-transform-classes | ✔️ |
babel-plugin-transform-computed-properties | ✔️ |
babel-plugin-transform-destructuring | ✔️ |
babel-plugin-transform-dotall-regex | ❌ |
babel-plugin-transform-duplicate-keys | ✔️ |
babel-plugin-transform-exponentiation-operator | ✔️ |
babel-plugin-transform-flow-comments | ❌ |
babel-plugin-transform-flow-strip-types | ❌ |
babel-plugin-transform-for-of | ✔️ |
babel-plugin-transform-function-name | ✔️ |
babel-plugin-transform-instanceof | ✔️ |
babel-plugin-transform-jscript | ❌ |
babel-plugin-transform-literals | ✔️ |
babel-plugin-transform-member-expression-literals | ✔️ |
babel-plugin-transform-modules-amd | ✔️ |
babel-plugin-transform-modules-commonjs | ✔️ |
babel-plugin-transform-modules-systemjs | ❌ |
babel-plugin-transform-modules-umd | ✔️ |
babel-plugin-transform-named-capturing-groups-regex | ❌ |
babel-plugin-transform-new-target | ❌ |
babel-plugin-transform-object-assign | ❌ |
babel-plugin-transform-object-set-prototype-of-to-assign | ❌ |
babel-plugin-transform-object-super | ❌ |
babel-plugin-transform-object-rest-spread | ✔️ |
babel-plugin-transform-parameters | ✔️ |
babel-plugin-transform-property-literals | ✔️ |
babel-plugin-transform-property-mutators | ❌ |
babel-plugin-transform-proto-to-assign | ❌ |
babel-plugin-transform-react-constant-elements | ❌ |
babel-plugin-transform-react-display-name | ✔️ |
babel-plugin-transform-react-inline-elements | ❌ |
babel-plugin-transform-react-jsx | ✔️ |
babel-plugin-transform-react-jsx-compat | ❌ |
babel-plugin-transform-react-jsx-self | ✔️ |
babel-plugin-transform-react-jsx-source | ✔️ |
babel-plugin-transform-regenerator | ✔️ |
babel-plugin-transform-reserved-words | ✔️ |
babel-plugin-transform-runtime | ✔️ |
babel-plugin-transform-shorthand-properties | ✔️ |
babel-plugin-transform-spread | ✔️ |
babel-plugin-transform-sticky-regex | ✔️ |
babel-plugin-transform-strict-mode | ✔️ |
babel-plugin-transform-template-literals | ✔️ |
babel-plugin-transform-typeof-symbol | ✔️ |
babel-plugin-transform-typescript | ✔️ |
babel-plugin-transform-unicode-regex | ❌ |
babel-preset-env | ✔️ |
babel-preset-env-standalone | ❌ |
babel-preset-flow | ❌ |
babel-preset-react | ✔️ |
babel-preset-stage-0 | ❌ |
babel-preset-stage-1 | ❌ |
babel-preset-stage-2 | ❌ |
babel-preset-stage-3 | ❌ |
babel-preset-typescript | ✔️ |
babel-register | ✔️ (swc-register) |
@swc 官方插件庫
@swc/cli
swc 命令行
Usage
Run the following to download pre-built binaries:
npm i -D @swc/cli @swc/core
Then, you can transpile your files:
# Transpile one file and emit to stdout
npx swc ./file.js
# Transpile one file and emit to `output.js`
npx swc ./file.js -o output.js
# Transpile and write to /output dir
npx swc ./my-dir -d output
Options
--filename (-f)
Filename to use when reading from stdin. This will be used in source maps and errors.
npx swc -f input.js
--config-file
Path to a .swcrc
file to use.
npx swc input.js --config-file .swcrc
--env-name
The name of the 'env' to use when loading configs and plugins. Defaults to the value of SWC_ENV
, or else NODE_ENV
, or else development
.
npx swc input.js --env-name='test'
--no-swcrc
Whether or not to look up .swcrc
files.
npx swc input.js --no-swcrc
--ignore
List of glob paths to not compile.
npx swc src --ignore **/*.test.js
--only
List of glob paths to only compile
Example:
npx swc src --only **/*.js
--watch (-w)
To automatically recompile files on changes, install chokidar
:
npm i -D chokidar
Then, add the -w
flag:
npx swc input.js -w
--quiet (-q)
Suppress compilation output.
npx swc input.js -q
--source-maps (-s)
Values: true|false|inline|both
npx swc input.js -s
--source-map-target
Define the file
for the source map.
npx swc input.js -s --source-map-target input.map.js
--source-file-name
Set sources[0]
on returned source map
--source-root
The root from which all sources are relative.
--out-file (-o)
Compile all input files into a single file.
npx swc input.js -o output.js
--out-dir (-d)
Compile an input directory of modules into an output directory.
npx swc src -d dist
--copy-files (-D)
When compiling a directory, copy over non-compilable files.
npx swc src --copy-files
--include-dotfiles
Include dotfiles when compiling and copying non-compilable files.
npx swc src --include-dotfiles
--config (-C)
Override a config from .swcrc
file.
npx swc src -C module.type=amd -C module.moduleId=hello
--sync
Invoke swc synchronously. Useful for debugging.
npx swc src --sync
--log-watch-compilation
Log a message when a watched file is successfully compiled.
npx swc input.js --log-watch-compilation
--extensions
Use specific extensions.
@swc/core
這些是核心 SWC API,主要對構建工具者有用。
transform
const swc = require("@swc/core");
swc
.transform("source code", {
// Some options cannot be specified in .swcrc
filename: "input.js",
sourceMaps: true,
// Input files are treated as module by default.
isModule: false,
// All options below can be configured via .swcrc
jsc: {
parser: {
syntax: "ecmascript",
},
transform: {},
},
})
.then((output) => {
output.code; // transformed code
output.map; // source map (in string)
});
transformSync
Returns { code: string, map?: string }
transformFile
Returns Promise<{ code: string, map?: string }>
transformFileSync
Returns { code: string, map?: string }
Options
This still needs to be documented. Contributions welcome!
@swc/wasm-web
該模塊允許您使用 WebAssembly 在瀏覽器內同步轉換代碼。(機翻,諒解,大意就是能直接在瀏覽器內使用 wasm 咯)
Usage
You must first initialize the module before you can use it.
import { useEffect, useState } from "react";
import initSwc, { transformSync } from "@swc/wasm-web";
export default function App() {
const [initialized, setInitialized] = useState(false);
useEffect(() => {
async function importAndRunSwcOnMount() {
await initSwc();
setInitialized(true);
}
importAndRunSwcOnMount();
}, []);
function compile() {
if (!initialized) {
return;
}
const result = transformSync(`console.log('hello')`, {});
console.log(result);
}
return (
<div className="App">
<button onClick={compile}>Compile</button>
</div>
);
}
@swc/jest
爲了讓您的 Jest 測試運行得更快,您可以使用 drop-in Rust 替換 替換默認的基於 JavaScript 的運行程序 (ts-jest
) SWC。
Installation
npm i -D jest @swc/jest
Usage
Inside jest.config.js
, configure Jest to use SWC:
module.exports = {
transform: {
"^.+\\.(t|j)sx?$": ["@swc/jest"],
},
};
swc-loader
Webpack loader
Installation
npm i --save-dev @swc/core swc-loader
Usage
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules)/,
use: {
// `.swcrc` can be used to configure swc
loader: "swc-loader"
}
}
];
}
React Development
The jsc.transform.react.development
option is automatically set based on the webpack mode
.
其他推薦閱讀
示例項目
- swc react 示例
- swc react typescript emotion 示例 css in js,核心就一個 d.ts 文件