首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >错误:无法在JS同构应用中解析'fs‘

错误:无法在JS同构应用中解析'fs‘
EN

Stack Overflow用户
提问于 2019-04-23 20:50:31
回答 1查看 150关注 0票数 1

我正在构建一个Typescript包,这应该是在前端和后端运行。我使用这个包来识别环境是浏览器还是节点:https://www.npmjs.com/package/browser-or-node入口点是单个index.js文件

我可以毫无问题地构建和发布应用程序,但是当我导入它并尝试在浏览器中运行它时,我得到了错误消息Module not found: Error: Can't resolve 'fs'

这似乎是因为我正在导入fs,这是一个节点方法,而浏览器不知道该做什么。

在这种情况下,避免此问题的最佳实践是什么?如果我不导入这个模块,这个库就能正常工作。

我的package.json:

代码语言:javascript
复制
"license": "MIT",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "build": "tsc",
    "test": "mocha -r ts-node/register src/**/*.spec.ts"
  },
  "devDependencies": {
    "@types/chai": "^4.1.7",
    "@types/mocha": "^5.2.6",
    "@types/sinon": "^7.0.11",
    "@types/sinon-chai": "^3.2.2",
    "chai": "^4.2.0",
    "mocha": "^6.1.4",
    "sinon": "^7.3.2",
    "sinon-chai": "^3.3.0",
    "ts-node": "^8.1.0",
    "typescript": "^3.4.4"
  },
  "dependencies": {
    "@types/es6-promise": "^3.3.0",
    "axios": "^0.18.0",
    "browser-or-node": "^1.2.1",
    "dotenv": "^7.0.0"
  }

我的tsconfig.json:

代码语言:javascript
复制
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "outDir": "./dist",
    "strict": true,
    "noImplicitAny": false,
    "lib": [ "es2015" ]
  },
  "exclude":[
    "node_modules",
    "./dist",
    "./**/*.spec.ts",
    "./test/**/*.ts"
  ]
}

导致问题的函数:

代码语言:javascript
复制
import * as fs from 'fs';

export function saveTokensNode(data: any, path: string) {
    try {
        fs.writeFileSync(path, JSON.stringify(data))
    } catch (err) {
        console.error(err)
    }
}

我正在使用它的地方:

代码语言:javascript
复制
setCredentials(tokens) {
    if (isBrowser) {
        saveTokensStorage(tokens)
    }

    if (isNode) {
        saveTokensNode(tokens, 'temp/tokensToStore.json')
    }
}
EN

回答 1

Stack Overflow用户

发布于 2019-04-23 21:16:08

基本的答案是,您可以使用"browser" package.json field从浏览器包中排除模块。它得到了所有主流捆绑包的支持。

代码语言:javascript
复制
{
  "browser": {
    "fs": false
  }
}

然后,在browserify中,当您导入fs时,您将获得一个空对象。不过,我不确定其他捆绑包做了什么!

但实际上,您可以稍微改变一下,避免使用浏览器或节点包。您可以有两个文件用于令牌存储的节点和浏览器实现。例如,

代码语言:javascript
复制
// token-storage.js
import * as fs from "fs"
export function saveTokens() { /* Node implementation */ }

// token-storage.browser.js
export function saveTokens() { /* localStorage implementation */ }

您可以在它们之间切换,同样使用"browser“字段。

代码语言:javascript
复制
{
  "browser": {
    "./path/to/token-storage.js": "./path/to/token-storage.browser.js"
  }
}

然后,在模块中,您可以执行以下操作:

代码语言:javascript
复制
import { saveTokens } from "./token-storage.js"
function setCredentials (tokens) {
  saveTokens(tokens, 'temp/tokensToStore.json')
}

浏览器实现可以忽略文件路径,或者将其用作localStorage密钥名称。它将节点/浏览器决策本地化到令牌存储文件中,当您在其他地方使用它时,您不必考虑它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55811668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档