Обновление до 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 / sizes / core / translate '

В своей службе я объявляю 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. На стороне сервера я столкнусь со следующей ошибкой

ERROR ReferenceError: fs не определена

ps: мой проект следует структуре https://github.com/angular/universal-starter, config и зависимости


person David Dal Busco    schedule 06.05.2018    source источник
comment
попробуйте также объявить fs, declare var fs: any;   -  person John Velasquez    schedule 06.05.2018
comment
круто, это хороший обходной путь, который работает, спасибо, @JohnVelasquez - я позволю вам ответить на вопрос, а затем помечу его как решение   -  person David Dal Busco    schedule 06.05.2018
comment
попробуйте поставить это условие, когда вы используете fs - ›if(typeof window !== 'undefined')   -  person John Velasquez    schedule 06.05.2018
comment
это не поможет, проблема на стороне сервера, код также используется только на стороне сервера (isPlatformServer)   -  person David Dal Busco    schedule 06.05.2018
comment
См. Этот ответ stackoverflow.com/a/57506728/11127383   -  person Daniel Danielecki    schedule 15.08.2019


Ответы (12)


Обновление 2020

См. ответ Marc для Angular v9.

Обновление 2019

См. Комментарий, согласно @Tahlil, теперь это возможно. Это работает для Angular v8 (компилятор Ivy). см. Этот ответ. Он устанавливает для определенных модулей значение false для использования в браузере в package.json.

Исходный ответ

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

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

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

По этой теме есть открытый вопрос: https://github.com/angular/angular-cli/issues/10681

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

person David Dal Busco    schedule 07.05.2018
comment
Оказывается, на самом деле вы можете stackoverflow.com/questions/51087330/ - person Tahlil; 17.07.2019
comment
Моему ответу больше года. Я добавил в него комментарий. - person David Dal Busco; 18.07.2019

Поскольку предыдущие ответы довольно старые, можно выделить здесь, что обходной путь для Angular9 - просто добавить следующее в ваш package.json:

"browser": {
    "fs": false,
    "os": false,
    "path": false
  }

У меня это очень хорошо работает. Для справки, я нашел это решение на официальной странице tenorflow / tfjs Github здесь.

person Marc    schedule 15.08.2020
comment
Coolio. Обновил принятый ответ со ссылкой на ваш. - person David Dal Busco; 16.08.2020
comment
Лучший ответ для Angular 9+ - person Daniel Danielecki; 18.10.2020
comment
Хотел бы я проголосовать за этот ответ один раз за каждое найденное мной ложноположительное решение. В моем случае это решило ошибку ERROR in ./node_modules/foo/foo.js Module not found: Error: Can't resolve 'path' in 'my-app/node_modules/foo, где foo - это модуль, использующий path. :). В моем случае требовалось только "browser": { "path": false }. - person tresf; 22.10.2020
comment
Проверьте спецификацию поля браузера, чтобы узнать, почему оно работает (или нет): github .com / defunctzombie / package-browser-field-spec. - person j2L4e; 12.11.2020
comment
Решает проблему сборки; однако мое приложение больше не загружается должным образом Uncaught ReferenceError: __dirname is not defined at Object.vbkW (index.js:4) - person d4rty; 17.12.2020

Для тех, кто все еще ищет ответ, вот как мне удалось потребовать ('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' и т. Д., Компилятор angular не может скомпилировать код. Чтобы обойти это, как кто-то уже предлагал, добавьте (window as any).global = window; в ваш polyfills.ts.

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

person Nishkal Kashyap    schedule 02.11.2018
comment
У меня есть проект с зависимостью, в которой используются path и fs. Я выполнил вышеупомянутые шаги, но не могу решить проблему. - person Tanzeel; 21.11.2018
comment
Трудно сказать без какой-либо информации, какую версию angular, electronic, nodejs вы используете? - person Nishkal Kashyap; 21.11.2018
comment
Я намного ближе, чем был, но я получаю сообщение об ошибке TypeError: window.require is not a function при попытке использовать window['require']. Не знаю, как обойти это - person ntgCleaner; 28.02.2019
comment
@ntgCleaner попробуйте следующее: declare global { interface Window { require: NodeRequire; } } Затем используйте window ['require']. Если это была ошибка компилятора машинописного текста, она должна быть устранена с ее помощью. Если это не сработает, попробуйте следующее: window['require']=eval('require'). И окно использования ['require']. - person Nishkal Kashyap; 28.02.2019
comment
@NishkalKashyap после того, как попробовал то, что вы упомянули, и поигрался с этим еще, я просто не могу заставить его работать. Я пытаюсь выполнить простую очистку веб-страниц с помощью cheerio и request-prom, но они оба должны использовать require. Я буду продолжать пробовать - person ntgCleaner; 28.02.2019
comment
@ntgCleaner попробуйте добавить этот код в функцию создания электронов. у меня это сработало. webPreferences: { nodeIntegration: true }. см. этот ответ - person benshabatnoam; 19.08.2019
comment
отлично работает с электроном 4.1.0, Ionic 5 и angular 8 - person Mr. Ratnadeep; 03.01.2020

В 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'
      }
};
person bighairdave    schedule 13.09.2019

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

person John Velasquez    schedule 06.05.2018
comment
на самом деле, к сожалению, полностью проблему это не решает. это решение ng serve, но если я построю свой проект npm run build:ssr, а затем запустил его npm run serve, я столкнусь с ошибкой fs is not defined на стороне обслуживания :( - person David Dal Busco; 06.05.2018

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

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

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

person adamup    schedule 06.11.2018

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

"types": [
  "node"
]

в tsconfig.app.json

person Ebram    schedule 23.07.2019

В качестве альтернативы In 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.
    });
person Subrata Fouzdar    schedule 26.11.2018

Я запускаю приложение Angular в монорепозитории Angular CLI, настроенное с помощью схем Nx. Я делюсь кодом из каталога библиотеки.

При попытке использовать Typescript Enum из общей библиотеки внутри приложения Angular я получил:

Критическая зависимость: запрос зависимости - это выражение

Не могу разрешить "fs"

Включенный стек ошибок:

Это было странно, потому что на первый взгляд включение Enum не имело ничего общего с type-graphql.

Проблема оказалась связана с тем, что схемы type-graphql и перечисления Typescript были определены в одной и той же библиотеке. Извлечение перечислений в их собственную библиотеку решило проблему. Я не понимаю, почему произошла ошибка, но в любом случае решение сработало.

ИЗМЕНИТЬ

Итак, проблема заключалась в том, что согласно этой проблеме nx и эта проблема type-graphql, в какой-то момент, включая материал из библиотеки с TypeGraphQL, пытается объединить все ВведитеGraphQL в приложение браузера (декоратор @Input() кажется еще одним таким триггером).

Решение, если вы хотите включить классы TypeGraphQL в интерфейс, состоит в том, чтобы обновить конфигурацию веб-пакета . Это делается в приложении AngularCLI. включает несколько шагов.

person Derek Hill    schedule 07.02.2020

Если вы импортировали жасмин в свой файл спецификаций, чтобы избежать ошибки tslint, вам следует сделать следующее:

  1. Удалите import jasmine; из файла спецификации.
  2. Добавить jasmine в tsconfig.json
...
...
"compilerOptions": {
  ...
  ...
  "types": [
      "webpack-env",
      "jasmine"
  ]
  ...
  ...
}
...
...

person Yuvraj Patil    schedule 11.05.2020

добавьте строки ниже в свой package.json

  1. браузер: {fs: false, os: false, path: false}

Щелкните здесь, чтобы просмотреть образец изображения

person saikumar    schedule 02.10.2020

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

Итак, нужно сделать

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

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

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

В нашем приложении это избавилось от ошибки Module 'fs' not found.

person user428602    schedule 11.01.2019
comment
какое отношение к этому имеет advanced-json-path? - person FlavorScape; 26.11.2019