SWC 高级用法 #
性能优化 #
编译性能 #
优化目标环境 #
json
{
"jsc": {
"target": "es2020"
}
}
选择合适的目标可以减少转换工作量:
| 目标 | 转换量 | 兼容性 |
|---|---|---|
es5 |
最多 | 最广 |
es2015 |
中等 | 较广 |
es2020 |
最少 | 现代 |
禁用不必要的功能 #
json
{
"jsc": {
"parser": {
"syntax": "ecmascript",
"jsx": false,
"decorators": false,
"dynamicImport": false
}
}
}
使用 externalHelpers #
json
{
"jsc": {
"externalHelpers": true
}
}
需要安装 @swc/helpers:
bash
npm install @swc/helpers
并行处理 #
使用 Workers #
javascript
const swc = require('@swc/core');
const { Worker } = require('worker_threads');
async function parallelCompile(files) {
const workerCount = Math.min(files.length, 4);
const chunkSize = Math.ceil(files.length / workerCount);
const workers = [];
for (let i = 0; i < workerCount; i++) {
const chunk = files.slice(i * chunkSize, (i + 1) * chunkSize);
const worker = new Worker(`
const swc = require('@swc/core');
const fs = require('fs');
async function compile(files) {
const results = [];
for (const file of files) {
const code = fs.readFileSync(file, 'utf-8');
const result = await swc.transform(code, {
jsc: { parser: { syntax: 'ecmascript' } }
});
results.push({ file, code: result.code });
}
return results;
}
compile(${JSON.stringify(chunk)}).then(results => {
parentPort.postMessage(results);
});
`, { eval: true });
workers.push(new Promise((resolve) => {
worker.on('message', resolve);
}));
}
const results = await Promise.all(workers);
return results.flat();
}
缓存策略 #
文件系统缓存 #
javascript
const swc = require('@swc/core');
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const cacheDir = './.swc-cache';
function getCacheKey(file, config) {
const content = fs.readFileSync(file, 'utf-8');
const configStr = JSON.stringify(config);
return crypto
.createHash('md5')
.update(content + configStr)
.digest('hex');
}
async function compileWithCache(file, config) {
if (!fs.existsSync(cacheDir)) {
fs.mkdirSync(cacheDir, { recursive: true });
}
const cacheKey = getCacheKey(file, config);
const cacheFile = path.join(cacheDir, `${cacheKey}.js`);
if (fs.existsSync(cacheFile)) {
return fs.readFileSync(cacheFile, 'utf-8');
}
const code = fs.readFileSync(file, 'utf-8');
const result = await swc.transform(code, config);
fs.writeFileSync(cacheFile, result.code);
return result.code;
}
内存缓存 #
javascript
const swc = require('@swc/core');
const fs = require('fs');
const crypto = require('crypto');
const cache = new Map();
function getCacheKey(file, config) {
const content = fs.readFileSync(file, 'utf-8');
const configStr = JSON.stringify(config);
return crypto
.createHash('md5')
.update(content + configStr)
.digest('hex');
}
async function compileWithMemoryCache(file, config) {
const cacheKey = getCacheKey(file, config);
if (cache.has(cacheKey)) {
return cache.get(cacheKey);
}
const code = fs.readFileSync(file, 'utf-8');
const result = await swc.transform(code, config);
cache.set(cacheKey, result.code);
return result.code;
}
自定义转换 #
使用 Visitor 模式 #
javascript
const swc = require('@swc/core');
const code = `
function greet(name) {
console.log("Hello, " + name);
return "Greeted: " + name;
}
`;
const result = await swc.transform(code, {
jsc: {
parser: {
syntax: 'ecmascript',
},
experimental: {
plugins: [
// 自定义插件
],
},
},
});
AST 操作 #
javascript
const swc = require('@swc/core');
// 解析代码为 AST
const ast = await swc.parse(`
const x = 1;
const y = 2;
`, {
syntax: 'ecmascript',
});
console.log(JSON.stringify(ast, null, 2));
// 从 AST 生成代码
const { code } = await swc.print(ast, {
minify: false,
});
console.log(code);
增量编译 #
监听文件变化 #
javascript
const chokidar = require('chokidar');
const swc = require('@swc/core');
const fs = require('fs');
const path = require('path');
const config = {
jsc: {
parser: {
syntax: 'ecmascript',
},
target: 'es2015',
},
};
const compiledFiles = new Map();
async function compileFile(file) {
const stat = fs.statSync(file);
const lastModified = stat.mtimeMs;
if (compiledFiles.has(file)) {
const { mtime, code } = compiledFiles.get(file);
if (mtime === lastModified) {
return code;
}
}
const code = fs.readFileSync(file, 'utf-8');
const result = await swc.transform(code, config);
compiledFiles.set(file, {
mtime: lastModified,
code: result.code,
});
return result.code;
}
const watcher = chokidar.watch('./src/**/*.js');
watcher.on('change', async (file) => {
console.log(`File changed: ${file}`);
const result = await compileFile(file);
const outputFile = file.replace('src', 'dist');
fs.writeFileSync(outputFile, result);
console.log(`Compiled: ${outputFile}`);
});
增量构建 #
javascript
const swc = require('@swc/core');
const fs = require('fs');
const path = require('path');
const buildCache = new Map();
async function incrementalBuild(entry, config) {
const visited = new Set();
const queue = [entry];
const results = [];
while (queue.length > 0) {
const file = queue.shift();
if (visited.has(file)) continue;
visited.add(file);
const stat = fs.statSync(file);
const cacheKey = `${file}:${stat.mtimeMs}`;
let result;
if (buildCache.has(cacheKey)) {
result = buildCache.get(cacheKey);
} else {
const code = fs.readFileSync(file, 'utf-8');
result = await swc.transform(code, config);
buildCache.set(cacheKey, result);
}
results.push({ file, code: result.code });
// 解析依赖(简化示例)
const imports = parseImports(result.code);
queue.push(...imports);
}
return results;
}
function parseImports(code) {
const importRegex = /import\s+.*?\s+from\s+['"](.+?)['"]/g;
const imports = [];
let match;
while ((match = importRegex.exec(code)) !== null) {
imports.push(match[1]);
}
return imports;
}
类型生成 #
生成声明文件 #
SWC 可以配合 tsc 生成类型声明:
json
// tsconfig.json
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"outDir": "./dist"
}
}
bash
# 使用 SWC 编译代码
swc src -d dist
# 使用 tsc 生成声明
tsc --emitDeclarationOnly
自动类型生成脚本 #
javascript
const { execSync } = require('child_process');
const swc = require('@swc/core');
const fs = require('fs');
const path = require('path');
async function buildWithTypes() {
// 1. 使用 SWC 编译代码
console.log('Compiling with SWC...');
execSync('swc src -d dist', { stdio: 'inherit' });
// 2. 使用 tsc 生成类型声明
console.log('Generating type declarations...');
execSync('tsc --emitDeclarationOnly', { stdio: 'inherit' });
console.log('Build complete!');
}
buildWithTypes();
条件编译 #
环境变量注入 #
javascript
const swc = require('@swc/core');
const code = `
if (process.env.NODE_ENV === 'development') {
console.log('Debug info');
}
const apiUrl = process.env.API_URL;
`;
const result = await swc.transform(code, {
jsc: {
parser: {
syntax: 'ecmascript',
},
transform: {
optimizer: {
globals: {
vars: {
'process.env.NODE_ENV': JSON.stringify('production'),
'process.env.API_URL': JSON.stringify('https://api.example.com'),
},
},
},
},
},
});
条件编译插件 #
javascript
// 自定义条件编译逻辑
const swc = require('@swc/core');
const DEFINE = {
__DEV__: false,
__PROD__: true,
__VERSION__: '"1.0.0"',
};
const code = `
if (__DEV__) {
console.log('Development mode');
}
const version = __VERSION__;
`;
// 使用 define 选项
const result = await swc.transform(code, {
jsc: {
parser: {
syntax: 'ecmascript',
},
},
define: DEFINE,
});
代码分割优化 #
路由级分割 #
javascript
// 动态导入路由组件
const routes = {
home: () => import('./pages/Home.js'),
about: () => import('./pages/About.js'),
contact: () => import('./pages/Contact.js'),
};
async function loadRoute(name) {
const loader = routes[name];
if (loader) {
const module = await loader();
return module.default;
}
throw new Error(`Route ${name} not found`);
}
预加载策略 #
javascript
// 预加载关键资源
function preloadRoute(name) {
const link = document.createElement('link');
link.rel = 'prefetch';
link.href = `/dist/${name}.js`;
document.head.appendChild(link);
}
// 鼠标悬停时预加载
document.querySelector('a[href="/about"]').addEventListener('mouseenter', () => {
preloadRoute('about');
});
Source Map 优化 #
高级 Source Map 配置 #
json
{
"sourceMaps": true,
"sourceRoot": "/src",
"inlineSourcesContent": false,
"sourceMapTarget": "bundle.js"
}
Source Map 处理 #
javascript
const swc = require('@swc/core');
const fs = require('fs');
const path = require('path');
const { SourceMapConsumer, SourceMapGenerator } = require('source-map');
async function combineSourceMaps(maps) {
const generator = new SourceMapGenerator();
for (const map of maps) {
const consumer = await new SourceMapConsumer(map);
consumer.eachMapping((mapping) => {
generator.addMapping({
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn,
},
source: mapping.source,
original: {
line: mapping.originalLine,
column: mapping.originalColumn,
},
name: mapping.name,
});
});
}
return generator.toString();
}
最佳实践 #
1. 项目结构 #
text
my-project/
├── src/
│ ├── index.ts
│ ├── components/
│ └── utils/
├── dist/
│ ├── index.js
│ └── index.d.ts
├── .swcrc
├── tsconfig.json
└── package.json
2. 配置文件分离 #
javascript
// swc.config.js
const isDev = process.env.NODE_ENV !== 'production';
module.exports = {
jsc: {
parser: {
syntax: 'typescript',
tsx: true,
},
target: isDev ? 'es2020' : 'es2015',
minify: !isDev,
},
sourceMaps: true,
minify: !isDev,
};
3. npm scripts 优化 #
json
{
"scripts": {
"dev": "swc src -d dist -w -s inline",
"build": "swc src -d dist -C minify=true -s",
"build:analyze": "ANALYZE=true npm run build",
"typecheck": "tsc --noEmit",
"lint": "eslint src --ext .ts,.tsx",
"test": "jest",
"ci": "npm run lint && npm run typecheck && npm run test && npm run build"
}
}
4. CI/CD 配置 #
yaml
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
- name: Type check
run: npm run typecheck
- name: Test
run: npm run test
- name: Build
run: npm run build
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: dist
path: dist/
5. 性能监控 #
javascript
const swc = require('@swc/core');
const fs = require('fs');
async function buildWithMetrics() {
const start = Date.now();
const files = fs.readdirSync('./src').filter(f => f.endsWith('.ts'));
for (const file of files) {
const fileStart = Date.now();
const code = fs.readFileSync(`./src/${file}`, 'utf-8');
const result = await swc.transform(code, {
jsc: {
parser: { syntax: 'typescript' },
target: 'es2015',
},
});
fs.writeFileSync(`./dist/${file.replace('.ts', '.js')}`, result.code);
const fileEnd = Date.now();
console.log(`${file}: ${fileEnd - fileStart}ms`);
}
const end = Date.now();
console.log(`Total: ${end - start}ms`);
}
buildWithMetrics();
调试技巧 #
查看编译结果 #
javascript
const swc = require('@swc/core');
const code = `
const x = 1;
console.log(x);
`;
const result = await swc.transform(code, {
jsc: {
parser: { syntax: 'ecmascript' },
target: 'es2015',
},
});
console.log('Compiled code:');
console.log(result.code);
console.log('\nMetadata:');
console.log(JSON.stringify(result.map, null, 2));
分析 AST #
javascript
const swc = require('@swc/core');
const code = `const x = 1;`;
const ast = await swc.parse(code, {
syntax: 'ecmascript',
});
console.log(JSON.stringify(ast, null, 2));
错误处理 #
javascript
const swc = require('@swc/core');
async function safeCompile(code, config) {
try {
const result = await swc.transform(code, config);
return { success: true, code: result.code };
} catch (error) {
console.error('Compilation error:', error.message);
return { success: false, error: error.message };
}
}
总结 #
SWC 是一个强大且快速的 JavaScript/TypeScript 编译器,通过本系列文档的学习,你已经掌握了:
- 基础知识:SWC 的概念、历史和核心特点
- 安装配置:如何安装和配置 SWC
- 命令行工具:使用 CLI 进行编译和打包
- 配置详解:深入理解各种配置选项
- 编译转译:JavaScript/TypeScript 编译功能
- 代码压缩:优化代码体积
- 打包功能:使用 spack 打包项目
- 插件开发:开发自定义 SWC 插件
- 工具集成:与主流工具和框架集成
- 高级用法:性能优化和最佳实践
现在你已经具备了使用 SWC 进行高效前端开发的能力!
最后更新:2026-03-28