【问题标题】:NPM workspaces with Expo and Typescript带有 Expo 和 Typescript 的 NPM 工作区
【发布时间】:2021-06-12 14:17:07
【问题描述】:

我正在尝试在 Typescript Expo 项目中使用 NPM 7 工作区。 现在我想保持正常的 Expo 结构(使用根 App.tsx 文件),但我想隔离工作区中的部分代码。

我在工作区中编译 TS 代码时遇到问题。我尝试了很多方法来配置 TS 和/或 Webpack 配置,但没有成功。所以这里是重现它的最小文件结构:

package.json
tsconfig.json
App.tsx
/packages
  /core
    index.ts
    package.json

这里是根./package.json的相关部分

{
  "main": "node_modules/expo/AppEntry.js",
  "workspaces": [
    "packages/*"
  ],
  "scripts": {...},
  "dependencies": {...},
  "devDependencies": {...},
  "private": true
}

./tsconfig.json 是最低要求

{
  "extends": "expo/tsconfig.base",
  "compilerOptions": {
    "strict": true
  }
}

./packages/core/package.json 也很简单

{
  "name": "core",
  "private": true
}

./packages/core/index.ts 只是在此示例中导出 log() 函数

export function log(s: string) {
  console.log(s)
}

最后,在./App.tsx,只是简单地导入函数并尝试调用它

import { log } from 'core'
log('hello')
//...

无法编译

当我尝试为网络构建时(例如expo build:web),我遇到以下错误

✖ Expo Webpack
  Compiled with some errors in 1.62s

Failed to compile.

[path]/node_modules/core/index.ts 1:21
Module parse failed: Unexpected token (1:21)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
> export function log(s: string) {
|   console.log(s)
| }

我并不感到惊讶,因为 /node_modules 目录被自愿排除在外。

所以我的问题是我需要做什么才能编译工作区代码?我希望它可以即时工作(即:未预编译),就像它是我项目中的一些常规文件一样。真的可行吗?

一些失败的修复尝试

我主要尝试调整 tsconfig 以使其正常工作(尽管我想知道它是否会改变任何东西)

#1

我尝试在./tsconfig.json 中添加"include": ["./node_modules/core"],没有效果(同样的错误)。

#2

我尝试使用复合选项创建以下/packages/core/tsconfig.json

{
  "extends": "expo/tsconfig.base",
  "compilerOptions": {
    "strict": true,
    "composite": true
  }
}

并在根tsconfig.json中引用了它

{
  "extends": "expo/tsconfig.base",
  "compilerOptions": {
    "strict": true
  },
  "references": [{ "path": "./node_modules/core" }]
  // or even with:
  "references": [{ "path": "./packages/core" }]
}

没有效果(同样的错误)。

非常感谢

【问题讨论】:

    标签: typescript npm babeljs expo npm-workspaces


    【解决方案1】:

    我想出了一个我不太满意的解决方案,但至少它是有效的。这实际上很简单,我只是配置了 Webpack 来编译我的 packages/*(作为 node_modules 中的符号链接。

    所以我首先安装:

    $ npm i -D ts-loader@8 webpack@4.430
    

    版本在这里很重要,以与 Expo 41 使用的 webpack 版本保持一致。

    我还将我的包名(在/packages/core/package.json)重命名为@workspace/core,这样我的所有自定义包都在node_modules/@workspace 目录中。

    这也将使我们的配置更简单。

    运行 $ expo customize:web 是自定义 webpack 配置所必需的。它将产生一个webpack.config.js

    可以自定义如下:

    const createExpoWebpackConfigAsync = require('@expo/webpack-config')
    
    module.exports = async function (env, argv) {
      const config = await createExpoWebpackConfigAsync(env, argv)
    
      config.module.rules = [
        {
          // this is why I renamed my packages with the @workspaces prefix.
          test: /node_modules\/@workspaces\/(.*)\.ts$/, 
          use: [
            {
              loader: 'ts-loader',
              // force ts-loader to compile in node_modules
              options: { allowTsInNodeModules: true },
            },
          ],
        },
        ...config.module.rules,
      ]
    
      return config
    }
    
    

    如果有更清洁的解决方案,我不会感到惊讶。但现在我会坚持下去

    【讨论】:

      猜你喜欢
      • 2021-06-02
      • 1970-01-01
      • 2020-01-06
      • 2019-12-17
      • 2023-03-20
      • 1970-01-01
      • 2015-11-20
      • 2021-12-15
      • 2021-10-07
      相关资源
      最近更新 更多