【发布时间】:2020-09-05 11:28:20
【问题描述】:
我正在将我们的 React 应用程序的核心组件提取到一个单独的组件库中,以便在其他客户端应用程序中使用。这些组件使用 SVG 图标,通过 babel-loader 已经可以在原始应用程序中使用。
但是,由于组件是用 Typescript 编写的,据我所知,我需要 ts-loader 才能使库正常工作,即使我无法对此进行测试,因为我什至无法编译图书馆。为了能够完全导出 SVG,我还添加了 babel-loader 和 babel-plugin-named-asset-import。
这是我的项目结构:
.
├── config
│ └── webpack.config.js
├── global.d.ts
├── index.ts
├── package.json
├── package-lock.json
├── src
│ ├── assets
│ │ └── icons
│ │ ├── index.d.ts
│ │ ├── index.ts
│ │ └── upload.svg
│ ├── bar
│ │ └── index.ts
│ └── foo
│ ├── index.ts
│ └── Stuff.ts
└── tsconfig.json
webpack.config.json:
const path = require("path");
module.exports = {
entry: "./index.ts",
module: {
rules: [
{
test: /\.tsx?$/,
use: {
loader: "ts-loader",
},
exclude: /node_modules/,
},
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
loader: require.resolve("babel-loader"),
options: {
customize: require.resolve(
"babel-preset-react-app/webpack-overrides"
),
plugins: [
[
require.resolve("babel-plugin-named-asset-import"),
{
loaderMap: {
svg: {
ReactComponent: "@svgr/webpack?-svgo,+ref![path]",
},
},
},
],
],
},
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
},
};
tsconfig.json:
{
"include": ["./global.d.ts", "./index.ts", "src/**/*"],
"compilerOptions": {
"allowJs": false,
"jsx": "react",
"esModuleInterop": true,
"downlevelIteration": true,
"declaration": true,
"noEmit": false,
"outDir": "dist",
"moduleResolution": "node",
"module": "commonjs",
"target": "es5",
"lib": ["es5", "es6", "es7", "es2017", "dom"],
"sourceMap": true,
"typeRoots": ["./node_modules/@types", "./@types"],
"resolveJsonModule": true
}
}
global.d.ts - 我发现这里的declare module 部分完全没有效果,无论有没有它我都会得到相同的结果。
import 'jest-dom/extend-expect';
declare module '*.svg' {
const content: string;
export default content;
}
./src/assets/icons/index.ts 应该负责导出所有可用的图标供其他文件导入。
export { ReactComponent as Add } from "./add.svg";
./src/demo/index.ts 包含“使用”此 SVG 的代码:
import { Add } from "../assets/icons";
export default {
Add,
};
根目录下的index.ts包含相同的内容来演示我的问题的不一致:
import { Add } from "../assets/icons";
export default {
Add,
};
到目前为止一切顺利,我想,所以我用npx webpack --config ./config/webpack.config.js 运行 webpack,结果整个事情都失败了,并出现了这个错误消息:
ERROR in C:\work\tstest\src\demo\index.ts
[tsl] ERROR in C:\work\tstest\src\demo\index.ts(1,21)
TS2306: File 'C:/work/tstest/src/assets/icons/index.ts' is not a module.
这让我对几个问题完全困惑:
- 有问题的文件怎么不是模块?很高兴知道是什么阻止了 ts-loader 正确识别它
-
./src/demo/index.ts和./index.ts在内容上是 100% 相同的。尽管如此,编译适用于一个文件,但不适用于另一个。为什么会这样?这种行为记录在哪里? - 我做错了什么?
- 正确的方法是什么?
我想这是因为在 babel-loader 完成它的工作之后,./src/assets/icons/index.ts 看起来不像 ts-loader 想要的那样,但这并不能完全解释如何处理具有相同内容的两个文件不同。
【问题讨论】:
标签: reactjs typescript webpack babel-loader