You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Webpack编译TS版CRA供其他React应用引入并处理SCSS

实现可嵌入React类库的Webpack构建方案

需求背景

你需要将基于TypeScript开发的Create React App项目(MyApp)作为依赖嵌入现有React应用(ExistingApp)运行,预期引入方式如下:

import App from "@MyApp/src"

function ExistingApp() {
   return (
     <div className="App">
       <App />
     </div>
   );
}

export default ExistingApp;

构建要求:

  • 基于Webpack完成TS/TSX转译、样式处理等全流程编译
  • 保留原有文件夹结构,不将所有代码合并为单个JS bundle
  • 解决单独执行tsc --module commonjs --outDir dist时,.scss文件未被处理、无法输出到dist目录的问题

实施步骤

1. 安装构建依赖

执行命令安装所有必需的构建工具和loader:

npm install webpack webpack-cli typescript ts-loader sass sass-loader css-loader mini-css-extract-plugin glob -D

2. 编写Webpack配置文件

在MyApp根目录新建webpack.config.js,核心逻辑为自动扫描src下所有业务文件作为独立入口,按原目录结构输出编译产物,分别处理TS、SCSS、静态资源三类文件:

const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

// 扫描src目录下所有ts/tsx文件作为构建入口,保留原文件路径映射
const entryMap = glob.sync('./src/**/*.{ts,tsx}').reduce((entry, filePath) => {
  const distPath = filePath.replace(/^\.\/src\//, '').replace(/\.(ts|tsx)$/, '');
  entry[distPath] = filePath;
  return entry;
}, {});

module.exports = {
  mode: process.env.NODE_ENV || 'production',
  entry: entryMap,
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js',
    libraryTarget: 'commonjs2', // 输出CommonJS格式模块,适配宿主项目的导入方式
    clean: true // 构建前清空旧的dist目录
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx', '.scss']
  },
  externals: {
    // 将react、react-dom标记为外部依赖,和宿主ExistingApp共用实例,避免重复打包引发hooks报错
    react: 'commonjs react',
    'react-dom': 'commonjs react-dom'
  },
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        exclude: /node_modules/,
        use: 'ts-loader'
      },
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader, // 抽离css为独立文件,不嵌入JS
          'css-loader',
          'sass-loader' // 编译scss为标准css
        ]
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif|woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
        generator: {
          filename: '[path][name][ext]' // 静态资源按原目录结构输出
        }
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].css' // 输出的css文件保持和对应ts/tsx文件一致的路径
    })
  ]
};

3. 调整配套配置

  • 检查tsconfig.json的核心配置项,保证模块解析正常:
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "module": "ESNext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src"]
}
  • 修改MyApp下package.json的字段,适配包引入规则:
{
  "name": "@MyApp",
  "main": "dist/index.js",
  "types": "src/index.ts",
  "files": ["dist"],
  "scripts": {
    "build": "webpack"
  }
}

4. 执行构建

在MyApp目录下执行npm run build,生成的dist目录会完整复现src的文件夹结构:

  • 所有.ts/.tsx文件转译为同路径同名的.js文件
  • 所有.scss文件编译为同路径同名的.css文件,JS中引入的样式会被自动关联
  • 图片、字体等静态资源按原路径输出
  • 不存在单bundle打包的问题,宿主ExistingApp安装MyApp依赖后可直接按预期方式引入使用

可选优化

如果项目中存在全局scss变量、公共混入,可以在sass-loader的配置项中添加additionalData字段全局注入,不需要每个文件手动引入:

{
  loader: 'sass-loader',
  options: {
    additionalData: `@use "@/styles/variables.scss" as *;`
  }
}

内容的提问来源于stack exchange,提问作者Tatenda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:06:54