可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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
回答1:
Ok after hours I come to the conclusion with the answers I gathered that the real answer is:
You can't use fs
anymore in Angular v6
Furthermore, since it's not possible anymore to eject the webpack configuration, there is no way to tell webpack to ignore the fs require
There is an open issue about this subject: https://github.com/angular/angular-cli/issues/10681
P.S.: I was using fs to load the translations on the server side, I overcome the problem by following solution of @xuhcc, see https://github.com/ngx-translate/core/issues/754
Update 2019
See comment, according @Tahlil it is now possible. I didn't tried out.
回答2:
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.
回答3:
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:
- run
npm i -D @angular-builders/custom-webpack
- 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
- Create your custom
webpack.config.js
- in this case it would look like this:
module.exports = {
node: {
fs: 'empty'
}
};
回答4:
You can declare the fs
also by doing this declare var fs: any;
回答5:
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
回答6:
Alternatively
In NativeScript File is implemented as part of the file system module.
To use it you have to import it in your code behind file.
e.g.
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:
Apparently advanced-json-path resolves this issue in Angular 6 onwards if anyone is using fs
So one has to do an
npm i advanced-json-path --save-dev
as it is a dev dependency (at least in my case)
as of this message instance, it is version 1.0.8
Then the Module 'fs' not found doesn't occur.
package.json
{
....
"advanced-json-path": "^1.0.8",
}
In our application it got rid of the Module 'fs' not found error.
回答8:
I fixed this by adding
"types": [
"node"
]
in tsconfig.app.json
回答9:
I am running an Angular app inside an Angular CLI monorepo, set up with the help of Nx schematics. I’m sharing code from a lib directory.
When trying to use a Typescript Enum from a shared lib inside the Angular app I got:
Critical dependency: the request of a dependency is an expression
Can't resolve 'fs'
The error stack involved:
- type-graphql, specifically loadResolversFromGlob
- glob
- fs.realpath
It was strange because on the face of if the inclusion of the Enum had nothing to do with type-graphql.
The issue turned out to be related to the fact that type-graphql schemas and Typescript Enums were defined in the same lib. Extracting the Enums into their own lib solved the problem. I’m not clear on why the error happened, but in any case the solution worked.