Update to Angular v6 - Module not found: Error: Ca

2020-02-10 03:46发布

I'm trying to migrate my Angular Universal project from Angular v5 to v6

I've got a service where I use fs to load the translation on the server side. Everything works well with Angular v5.

With Angular v6, when I run npm run start aka ng serve --proxy-config proxy.conf.json I face the following error

ERROR in ./src/providers/core/translate/translate-universal-loader.service.ts Module not found: Error: Can't resolve 'fs' in '/Users/me/Documents/projects/myproject/src/providers/core/translate'

In my service I declare fs like the following:

declare var require: any;
const fs = require('fs');

I also tried to declare it like following, but didn't help

import * as fs from 'fs';

To tell webpack to ignore fs I tried to add the following in my webpack.server.config.js without success

node: {
    fs: 'empty'
}

also tried with a webpack plugin, wasn't successful neither

new webpack.IgnorePlugin(/fs/)

but actually it's maybe not the config use by ng serve but I don't know if I could still eject the configuration with v6?

anyone has got an idea?

UPDATE

If I declare fs as any it solves the problem for ng serve but unfortunately it will not work on the server side after npm run build:ssr and run npm run serve. On the server side I will then face the following error

ERROR ReferenceError: fs is not defined

p.s.: my project follows https://github.com/angular/universal-starter structure, config and dependencies

9条回答
唯我独甜
2楼-- · 2020-02-10 04:08

In Angular 8, you can now use Angular Builders to specify a web.config.js which extends the virtual config produced by Angular.

This blogpost explains it quite well.

tldr:

  1. run npm i -D @angular-builders/custom-webpack
  2. edit your angular.json file architect.serve and architect.build to tell it to use the custom-webpack module to extend the virtual config with your webpack.config.js file
  3. Create your custom webpack.config.js - in this case it would look like this:
module.exports = {
    node: {
        fs: 'empty'
      }
};
查看更多
Juvenile、少年°
3楼-- · 2020-02-10 04:09

For anyone still looking for an answer, here's how I managed to require('fs') in my angular 7 app. Or for that matter, any other node module.

Versions

Angular CLI: 7.0.4
Node: 10.13.0
OS: win32 x64
"@angular/animations": "~7.0.0",
"@angular/common": "~7.0.0",
"@angular/compiler": "~7.0.0",
"@angular/core": "~7.0.0",
"@angular/forms": "~7.0.0",
"@angular/http": "~7.0.0",
"@angular/platform-browser": "~7.0.0",
"@angular/platform-browser-dynamic": "~7.0.0",
"@angular/router": "~7.0.0",
"@angular-devkit/build-angular": "~0.10.0",
"@angular/cli": "~7.0.4",
"@angular/compiler-cli": "~7.0.0",
"@angular/language-service": "~7.0.0",
"electron": "^3.0.7",
"typescript": "~3.1.1"

1. Install @types/node

npm install --save-dev @types/node

2. Modify tsconfig.json

Take note of "allowSyntheticDefaultImports" flag. It must be set to true.

{
  "compileOnSave": false,
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "types": [
      "node"
    ],
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "strict": false
  }
}

3. Require fs

import { Component } from '@angular/core';
import { } from 'electron';
import Fs from 'fs';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  constructor() {
    //check if platform is electron
    let isElectron: boolean = window && window['process'] && window['process'].type;

    if (isElectron) {
      let fs: typeof Fs = window['require']('fs');
      let app: Electron.App = window['require']('electron').remote;
      console.log(fs, app, window['process']);
    }
  }
}

Note: The import statements at the top of the file are just to provide for type information. The variable values are set using node require.

For updates, Track the issue here

https://github.com/angular/angular-cli/issues/9827

Edit:

Turns out, that if your project has dependencies that require 'fs', 'path', 'child_process' etc. The angular compiler fails to compile the code. To get around this, as someone has already suggested, add (window as any).global = window; to your polyfills.ts.

In my case, I had chokidar, node-pty and electron as a dependency. This worker for me.

查看更多
女痞
4楼-- · 2020-02-10 04:10

The accepted answer is correct; you can't use fs anymore in Angular v6+.

However, this alternative builder (it's an extension to the Angular CLI) allows you to target an Electron environment and have full access to Electron's features:

https://github.com/angular-guru/electron-builder

查看更多
登录 后发表回答