Обновить до Angular v6 - Модуль не найден: Ошибка: не удается разрешить 'fs'

Я пытаюсь перенести проект Angular Universal из Angular v5 в v6

У меня есть сервис, где я использую fs для загрузки перевода на стороне сервера. Все хорошо работает с Angular v5.

В Angular v6, когда я запускаю npm run start aka ng serve --proxy-config proxy.conf.json я сталкиваюсь со следующей ошибкой

ОШИБКА в. /src/providers/core/translate/translate-universal-loader.service.ts Модуль не найден: Ошибка: не удается разрешить 'fs' в '/Users/me/Documents/projects/myproject/src/provider/ядро /переводить"

В моем сервисе я объявляю fs следующим образом:

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

Я также пытался объявить это следующим образом, но не помогло

import * as fs from 'fs';

Чтобы сказать webpack игнорировать fs, я безуспешно пытался добавить следующее в мой webpack.server.config.js

node: {
    fs: 'empty'
}

также пытался с плагином WebPack, не удалось ни

new webpack.IgnorePlugin(/fs/)

но на самом деле это, возможно, не использование конфигурации с помощью ng serve но я не знаю, смогу ли я извлечь конфигурацию с v6?

У кого-нибудь есть идея?

ОБНОВИТЬ

Если я объявлю fs как что- any это решит проблему для ng serve но, к сожалению, он не будет работать на стороне сервера после npm run build:ssr и npm run serve. На стороне сервера я столкнусь со следующей ошибкой

ОШИБКА ReferenceError: fs не определена

PS: мой проект следует https://github.com/angular/universal-starter структура, конфигурации и зависимости

Ответ 1

Хорошо, после нескольких часов я прихожу к выводу с ответами, которые я собрал, что настоящий ответ:

Вы не можете больше использовать fs в Angular v6

Кроме того, поскольку больше невозможно извлечь конфигурацию веб-пакета, нет способа сказать веб-пакету игнорировать требование fs

Существует открытый вопрос на эту тему: https://github.com/angular/angular-cli/issues/10681

PS: я использовал fs для загрузки переводов на стороне сервера, я преодолел проблему, решив следующее решение @xuhcc, см. Https://github.com/ngx-translate/core/issues/754

Обновление 2019

Смотрите комментарий, по словам @Tahlil, теперь это возможно. Я не пробовал.

Ответ 2

Для тех, кто все еще ищет ответ, вот как мне удалось потребовать ('fs') в моем приложении angular 7. Или, в этом отношении, любой другой узел модуля.

Версии

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. Установите @types/node

npm install --save-dev @types/node

2. Изменить tsconfig.json

Обратите внимание на флаг "allowSyntheticDefaultImports". Должно быть установлено значение 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. Требовать фс

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']);
    }
  }
}

Примечание. Операторы импорта в верхней части файла служат только для предоставления информации о типе. Значения переменных устанавливаются с использованием узла require.

Для обновления, отследить проблему здесь

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

Редактировать:

Оказывается, если у вашего проекта есть зависимости, require 'fs', 'path', 'child_process' и т.д. Угловой компилятор не может скомпилировать код. Чтобы обойти это, как кто-то уже предложил, добавьте (window as any).global = window; на ваши polyfills.ts.

В моем случае в качестве зависимости у меня был chokidar, node-pty и электрон. Это рабочий для меня.

Ответ 3

Вы также можете объявить fs, declare var fs: any;

Ответ 4

Принятый ответ правильный; вы больше не можете использовать fs в Angular v6+.

Однако этот альтернативный компоновщик (расширение Angular CLI) позволяет вам ориентироваться на среду Electron и иметь полный доступ к функциям Electron:

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

Ответ 5

Я исправил это, добавив

"types": [
  "node"
]

в tsconfig.app.json

Ответ 6

Альтернативно В NativeScript File реализован как часть модуля файловой системы. Чтобы использовать его, вы должны импортировать его в свой код за файлом. например

import * as fs from "file-system';

var documents = fs.knownFolders.documents();
var path = fs.path.join(documents.path, "FileFromPath.txt");
var file = fs.File.fromPath(path);

// Writing text to the file.
file.writeText("Something")
    .then(function () {
        // Succeeded writing to the file.
    }, function (error) {
        // Failed to write to the file.
    });

Ответ 7

Очевидно продвинутый-json-путь решает эту проблему в Angular 6 и далее, если кто-либо использует fs

Так что нужно сделать

npm i advanced-json-path --save-dev

поскольку это зависимость от dev (по крайней мере, в моем случае) для данного экземпляра сообщения, это версия 1.0.8. Тогда модуль 'fs' not found не возникает.

package.json
{
    ....
   "advanced-json-path": "^1.0.8",
}

В нашем приложении он избавился от ошибки модуля 'fs' not found.

Ответ 8

В Angular 8 теперь можно использовать Angular Builders, чтобы указать web.config.js, который расширяет виртуальную конфигурацию, создаваемую Angular.

Этот пост объясняет это довольно хорошо.

tldr:

  1. запустить npm i -D @angular-builders/custom-webpack
  2. отредактируйте файл angular.json architect.serve и architect.build, чтобы он сказал использовать модуль custom-webpack для расширения виртуальной конфигурации с вашим файлом webpack.config.js
  3. Создайте свой собственный webpack.config.js - в этом случае это будет выглядеть так:
module.exports = {
    node: {
        fs: 'empty'
      }
};