Skip to content
New issue

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

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

Already on GitHub? Sign in 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.

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

No branches or pull requests

1 participant