sindresorhus / ow

Function argument validation for humans
https://sindresorhus.com/ow/
MIT License
3.8k stars 105 forks source link

Not working in browser #160

Closed Riim closed 4 years ago

Riim commented 4 years ago

Error: Can't resolve 'fs' in './node_modules/ow/dist/source'

Section browser in package.json is not actual.

sindresorhus commented 4 years ago

Section browser in package.json is not actual.

What does this mean?

bjmiller commented 4 years ago

I'm getting the same error. I'm using webpack, which may explain why fs is thought to be available when it isn't.

6XGate commented 4 years ago

@Riim probably means the path referenced by the browser field in package.json doesn't actually exist, which appears to be true.

Attempting to use this package in a browser via webpack will result in the error about the node fs module not existing.

Aqzhyi commented 4 years ago

TLDR

workaround:

with webpack.config.js target: 'node' getting resolved

detail:

ran into the same issue but with webpack.

reproduce:

  1. mkdir ow-fs-error && cd ow-fs-error
  2. npm init
  3. npm i typescript webpack webpack-cli ts-loader -D
  4. tsc --init
  5. create webpack.config.js
  6. create src/index.ts
  7. webpack --mode development

image

src/index.ts

import ow from 'ow'

const foo = ''

ow(foo, ow.string.nonEmpty)

webpack.config.js

const path = require('path')

module.exports = {
  entry: path.resolve(__dirname, 'src/index'),
  output: {
    filename: 'bundle.jsx',
  },
  resolve: {
    extensions: ['.js', '.tsx', '.ts'],
  },
  module: {
    rules: [
      {
        exclude: /node_modules/,
        test: /\.tsx?/,
        use: [
          {
            loader: 'ts-loader',
          },
        ],
      },
    ],
  },
}

package.json

{
  "name": "ow-fs-error",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "lezi.chen",
  "license": "ISC",
  "dependencies": {
    "ow": "^0.15.0"
  },
  "devDependencies": {
    "ts-loader": "^6.2.1",
    "typescript": "^3.7.4",
    "webpack": "^4.41.5",
    "webpack-cli": "^3.3.10"
  }
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true
  }
}
mnmkng commented 4 years ago

I'm still seeing this error with ow@0.17.0. Any tips?

ERROR in ./node_modules/ow/dist/source/index.js
Module not found: Error: Can't resolve 'fs' in '.../node_modules/ow/dist/source'
 @ ./node_modules/ow/dist/source/index.js 1:27109-27122
mnmkng commented 4 years ago

Ok, I'm no Webpack expert by far, actually I know almost nothing about it, but I feel the reason why it doesn't work is this:

ow is distributed as a compiled index.js with typings. Even though the browser field in package.json says that Webpack should replace ./dist/source/utils/infer-label.js with ./dist/source/utils/infer-label.browser.js there's no way it could do it, because the file does not exist in the published version.

I assume this works when you bundle from source, but when bundling ow as a dependency of something else, Webpack has no way of knowing what to replace in the index.js file and just cries when it sees fs.

Sadly, as I said, I'm no Webpack expert so I have no idea how to fix this, aside from maybe distributing ow in the original structure instead of the single index.js file. Not even sure it would help though.

av-pinzur commented 3 years ago

Another Workaround

Our team solved this issue by adding the following to our Webpack configuration:

  node: {
    fs: 'empty', // "ow" library tries to use "fs", but degrades gracefully.
  },
SoMuchSpace commented 3 years ago

Fix for webpack 5:

Add package process (webpack 5 does no longer include a polyfill for this Node.js variable and ow is using it):

npm install process --save-dev

and add this to config:

module.exports = {
    ...
    plugins: [
        ...
        new webpack.ProvidePlugin({
            process: 'process/browser',
        }),
        ...
    ],
    ...
    resolve: {
        fallback: {
            fs: false
        }
    },
    ...
}