Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Cannot Get Rid Of "Module not found: Error: Can't resolve 'fs/promises'" #4035

Closed
RomanoViolet opened this issue Dec 14, 2023 · 1 comment
Closed
Labels

Comments

@RomanoViolet
Copy link

Overview

In an angular 17 project running with webkit 5, I cannot get rid of the following error in a node module path_scurry which is not directly used anywhere in the client code::

./node_modules/path-scurry/dist/mjs/index.js:10:0-65 - Error: Module not found: Error: Can't resolve 'fs/promises' in '/workspaces/my-app/node_modules/path-scurry/dist/mjs'

Build Line

ng cache clean && ng build

What I Have Tried Already

Followed advise from #447, module-not-found-error-cant-resolve-fs-error-solved, and #1612, without success.

Important Artifacts

tsconfig.json

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "strictNullChecks": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noUnusedLocals": false,
    "noFallthroughCasesInSwitch": true,
    "noUnusedParameters": false,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "ES2022",
    "module": "es2020",
    "lib": ["es2020", "dom"],
    "skipLibCheck": true,
    "allowJs": true,
    "typeRoots": ["./node_modules/@types", "./typings"],
    "resolveJsonModule": true,
    "esModuleInterop": true,
    "paths": {
      "stream": ["./node_modules/stream-browserify"],
      "path": ["./node_modules/path-browserify"],
      "os": ["./node_modules/os-browserify"]
    }
  },
  "angularCompilerOptions": {
    "enableI18nLegacyMessageIdFormat": false,
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true,
    "types": ["node"]
  },

  "include": ["typings", "src/**/*", "src/declarations.d.ts"]
}

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "my-app": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        },
        "@schematics/angular:application": {
          "strict": true
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "outputPath": "dist/my-app",
            "index": "src/index.html",
            "main": "src/main.ts",
            "tsConfig": "tsconfig.app.json",
            "inlineStyleLanguage": "scss",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": [
              "./node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css",
              "./node_modules/primeicons/primeicons.css",
              "src/styles.scss",
              "./node_modules/primeng/resources/themes/arya-orange/theme.css",
              "./node_modules/primeng/resources/primeng.min.css"
            ],
            "scripts": [
              "./node_modules/jquery/dist/jquery.min.js",
              "./node_modules/jquery-ui-dist/jquery-ui.min.js",
              "./node_modules/draw2d/dist/draw2d.js"
            ],
            "customWebpackConfig": {
              "path": "./custom-webpack.config.js",
              "mergeRules": {
                "externals": "replace",
                "module.rules": "prepend"
              },
              "replaceDuplicatePlugins": true
            }
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            }
          },
          "defaultConfiguration": "development"
        },
        "serve": {
          "builder": "@angular-builders/custom-webpack:dev-server",
          "options": {},
          "configurations": {
            "production": {
              "browserTarget": "my-app:build:production"
            },
            "development": {
              "browserTarget": "my-app:build:development"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-builders/custom-webpack:extract-i18n",
          "options": {
            "browserTarget": "my-app:build",
            "customWebpackConfig": {
              "path": "./custom-webpack.config.js",
              "mergeRules": {
                "externals": "replace",
                "module.rules": "prepend"
              },
              "replaceDuplicatePlugins": true
            }
          }
        },
        "test": {
          "builder": "@angular-builders/custom-webpack:karma",
          "options": {
            "main": "src/test.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "inlineStyleLanguage": "scss",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": [
              "./node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css",
              "./node_modules/primeicons/primeicons.css",
              "src/styles.scss"
            ],
            "scripts": ["./node_modules/elkjs/lib/elk.bundled.js"],
            "customWebpackConfig": {
              "path": "./custom-webpack.config.js",
              "mergeRules": {
                "externals": "replace",
                "module.rules": "prepend"
              },
              "replaceDuplicatePlugins": true
            }
          }
        }
      }
    }
  },
  "cli": {
    "analytics": "3cb136ee-7850-47b8-ab00-9d4ab23d76e4"
  }
}

webpack.config.js

// Polyfills are not supported yet required in order to support older browsers.
// If polyfills are required, webpack may require additions.
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const { config } = require('process');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
  target: 'node',
  node: 'empty',
  mode: process.env.NODE_ENV || 'production',
  entry: './src/main.tsx',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      title: "Architects' Game",
      favicon: './src/globe.png'
    })
  ],
  devtool: 'inline-source-map',
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        terserOptions: {
          ecma: 5
        }
      })
    ]
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        exclude: /node_modules/,
        use: {
          loader: 'ts-loader'
        }
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          // without additional settings, this will reference .babelrc
          loader: 'babel-loader'
        }
      },
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        options: {
          transpileOnly: true
        }
      },
      {
        test: /\.css$/,
        include: path.join(__dirname, 'src'),
        use: [
          'style-loader',
          {
            loader: 'typings-for-css-modules-loader',
            options: {
              modules: true,
              namedExport: true
            }
          }
        ]
      },
      {
        test: /\.scss$/,
        use: [
          { loader: 'style-loader' }, // to inject the result into the DOM as a style block
          { loader: 'css-modules-typescript-loader' }, // to generate a .d.ts module next to the .scss file (also requires a declaration.d.ts with "declare modules '*.scss';" in it to tell TypeScript that "import styles from './styles.scss';" means to load the module "./styles.scss.d.td")
          { loader: 'css-loader', options: { modules: true } }, // to convert the resulting CSS to Javascript to be bundled (modules:true to rename CSS classes in output to cryptic identifiers, except if wrapped in a :global(...) pseudo class)
          { loader: 'sass-loader' } // to convert SASS to CSS
          // NOTE: The first build after adding/removing/renaming CSS classes fails, since the newly generated .d.ts typescript module is picked up only later
        ]
      }
    ]
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx', '.scss'],
    fallback: {
      stream: require.resolve('stream-browserify'),
      url: require.resolve('url'),
      fs: false,
      assert: false
    }
  },
  devServer: {
    contentBase: './dist',
    host: 'localhost',
    compress: false,
    port: 3000,
    disableHostCheck: false,
    overlay: {
      warnings: true,
      errors: true
    },
    hot: true,
    // https: true
    index: 'index.html'
  },
  stats: {
    colors: true
  }
};

Client Code

I have this client typescript prototype code, if it matters:

// https://nodejs.org/api/fs.html
import { promises as fsp } from 'fs';
import { rimraf } from 'rimraf';
export async function writeToFile(fileName: string, data: string): Promise<void> {
  rimraf.sync(fileName);
  await fsp.writeFile(fileName, data);
}

package.json

{
  "name": "my-app",
  "version": "1.0.0",
  "description": "For Frontend",
  "main": "custom-webpack.config.js",
  "scripts": {
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
  "repository": {
    "type": "git",
    "url": "github.com:REDACTED.git"
  },
  "keywords": [
    "Angular"
  ],
  "private": true,
  "author": "REDACTED",
  "dependencies": {
    "@angular-builders/custom-webpack": "^17.0.0",
    "@angular/cdk": "^17.0.1",
    "@angular/cli": "^17.0.1",
    "@angular/common": "^17.0.3",
    "@angular/compiler": "^17.0.3",
    "@angular/core": "^17.0.3",
    "@angular/forms": "^17.0.3",
    "@angular/material": "^17.0.1",
    "@angular/platform-browser": "^17.0.3",
    "@angular/platform-browser-dynamic": "^17.0.3",
    "@angular/router": "^17.0.3",
    "@mui/icons-material": "^5.14.18",
    "@ngstack/code-editor": "^5.1.0",
    "@types/jasmine": "^5.1.2",
    "@types/lodash": "^4.14.201",
    "angular-material-icons": "^0.7.1",
    "d3": "^7.8.5",
    "draw2d": "^1.0.38",
    "elkjs": "^0.8.2",
    "jquery": "^3.7.1",
    "jquery-ui": "^1.13.2",
    "jquery-ui-dist": "^1.13.2",
    "material-design-icons-iconfont": "^6.7.0",
    "monaco-editor": "^0.44.0",
    "primeicons": "^6.0.1",
    "primeng": "17.0.0-rc.1",
    "rimraf": "^5.0.5",
    "rxjs": "^7.8.1",
    "style-loader": "^3.3.3",
    "tslib": "^2.6.2",
    "typings-for-css-modules-loader": "^1.7.0",
    "util": "^0.12.5",
    "write-file": "^1.0.0",
    "zone.js": "^0.14.2"
  },
  "devDependencies": {
    "@babel/core": "^7.23.6",
    "@babel/preset-env": "^7.23.6",
    "@types/node": "^20.10.4",
    "babel-loader": "^9.1.3",
    "jasmine-core": "^5.1.1",
    "karma": "^6.4.2",
    "karma-jasmine": "^5.1.0",
    "karma-jasmine-html-reporter": "^2.1.0",
    "stream-browserify": "^3.0.0",
    "url": "^0.11.3"
  },
  "browser": {
    "fs": false,
    "path": false,
    "os": false,
    "net": false,
    "tls": false
  },
  "babel": {
    "presets": [
      "@babel/preset-env"
    ]
  }
}

Current Behavior

Error like so:

./node_modules/path-scurry/dist/mjs/index.js:10:0-65 - Error: Module not found: Error: Can't resolve 'fs/promises' in '/workspaces/sw-architects-tools/FrontEnd/my-app/node_modules/path-scurry/dist/mjs'

How To Reproduce
ng cache clean && ng build

Expected behavior

Expect no compilation error related around fs/promises, especially with node module not included directly in the client code, here path_scurry.

Screenshots
Nothing in addition to error message already provided above

Please paste the results of npx webpack-cli info here, and mention other relevant information

  System:
    OS: Linux 5.15 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)
    CPU: (12) x64 AMD Ryzen 5 3600 6-Core Processor
    Memory: 5.67 GB / 15.54 GB
  Binaries:
    Node: 20.10.0 - /usr/bin/node
    npm: 10.2.3 - /usr/bin/npm
  Packages:
    babel-loader: ^9.1.3 => 9.1.3 
    style-loader: ^3.3.3 => 3.3.3 
    typings-for-css-modules-loader: ^1.7.0 => 1.7.0 

Additional context

None

@RomanoViolet
Copy link
Author

RomanoViolet commented Dec 14, 2023

Well, I localized the error to the inclusion of rimraf module:

import { rimraf } from 'rimraf';

I removed it, and I am good now.

I am closing this ticket since I am unblocked, but I am curious about the behavior of rimraf.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant