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 编译器,通过本系列文档的学习,你已经掌握了:

  1. 基础知识:SWC 的概念、历史和核心特点
  2. 安装配置:如何安装和配置 SWC
  3. 命令行工具:使用 CLI 进行编译和打包
  4. 配置详解:深入理解各种配置选项
  5. 编译转译:JavaScript/TypeScript 编译功能
  6. 代码压缩:优化代码体积
  7. 打包功能:使用 spack 打包项目
  8. 插件开发:开发自定义 SWC 插件
  9. 工具集成:与主流工具和框架集成
  10. 高级用法:性能优化和最佳实践

现在你已经具备了使用 SWC 进行高效前端开发的能力!

最后更新:2026-03-28