简体   繁体   English

错误:无法解析JS isomorphic app中的'fs'

[英]Error: Can't resolve 'fs' in JS isomorphic app

I am building a Typescript package which should be running on both front end and back end. 我正在构建一个应该在前端和后端运行的Typescript包。 I am using this package to recognise if environment is browser or node: https://www.npmjs.com/package/browser-or-node The entry point is a single index.js file 我正在使用此包来识别环境是浏览器还是节点: https//www.npmjs.com/package/browser-or-node入口点是单个index.js文件

I can build and publish the application with no issue however when I import it and try to run it in the browser I get the error message Module not found: Error: Can't resolve 'fs' 我可以构建和发布应用程序没有问题,但是当我导入它并尝试在浏览器中运行它时我得到错误消息Module not found: Error: Can't resolve 'fs'

This seems to come from the fact that I am importing fs which is a node method and the browser doesn't know what to do. 这似乎来自于我导入fs这是一个节点方法,浏览器不知道该怎么做。

What is the best practices in this case to avoid this issue? 在这种情况下,为避免此问题,最佳做法是什么? If I don't import that module the library works just fine. 如果我不导入该模块,那么库工作正常。

My package.json: 我的package.json:

"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"
  }

My tsconfig.json: 我的tsconfig.json:

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

The function that causes the issue: 导致问题的功能:

import * as fs from 'fs';

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

Where I am using it: 我在哪里使用它:

setCredentials(tokens) {
    if (isBrowser) {
        saveTokensStorage(tokens)
    }

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

The basic answer is that you can use the "browser" package.json field to exclude a module from browser bundles. 基本答案是您可以使用“browser”package.json字段从浏览器包中排除模块。 It's supported by all major bundlers. 它得到了所有主要捆绑商的支持。

{
  "browser": {
    "fs": false
  }
}

Then, in browserify, you'll get an empty object when you import fs . 然后,在browserify中,导入fs时将获得一个空对象。 I'm not sure what other bundlers do, though! 不过我不确定其他捆绑商会做什么!


But you can actually do this slightly differently and avoid the need for a browser-or-node package. 但实际上你可以稍微改变一下,避免使用浏览器或节点包。 You could have two files for the node and browser implementations of token storage. 您可以为令牌存储的节点和浏览器实现提供两个文件。 For example, 例如,

// token-storage.js
import * as fs from "fs"
export function saveTokens() { /* Node implementation */ }

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

You can switch between them, again using the "browser" field. 您可以使用“浏览器”字段再次切换它们。

{
  "browser": {
    "./path/to/token-storage.js": "./path/to/token-storage.browser.js"
  }
}

Then, in your module, you can do: 然后,在您的模块中,您可以执行以下操作:

import { saveTokens } from "./token-storage.js"
function setCredentials (tokens) {
  saveTokens(tokens, 'temp/tokensToStore.json')
}

The browser implementation could ignore the file path, or use it as a localStorage key name. 浏览器实现可以忽略文件路径,或将其用作localStorage密钥名称。 It keeps the node/browser decision localised to the token-storage file and you don't have to think about it when you use it anywhere else. 它使节点/浏览器决策本地化到令牌存储文件,当您在其他地方使用它时,您不必考虑它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM