UPDATED:2020.02.13-似乎其他人也遇到了同样的问题-但是,没有解决方案。参见Github。
[尝试使用SystemJS构建Angular 4 Web应用程序时,出现了一组特定的GulpJS错误。
奇怪的是,通常此构建脚本有效。没有对GulpJS或SystemJS文件的编辑。我很好奇节点/ npm生态系统中的某些东西是否会改变这一假设。无论如何,您对修复的想法将不胜感激。
我的Windows 10计算机当前安装有节点版本10.14.0和npm版本6.9.0。
执行npm run build:dev
时,来自Gulp的错误在终端中显示为:
Unhandled rejection Error on fetch for app/main.js at file:///C:/Users/Mark/Desktop/Development/Bitbucket/Angular4App/app/main.js
Error: ENOENT: no such file or directory, open 'C:\Users\Mark\Desktop\Development\Bitbucket\Angular4App\app\main.js'
要清楚,上述文件为main.js
确实存在于文件系统中。
Gulp继续,构建的其余部分完成。但是在测试最终版本时,该应用程序不会加载,并且最终版本中缺少此资产:
最终构建工件明显缺少:
app/assets/js/app/app.js
gulpfile.js:
'use strict';
// Install required dependencies for gulp task automation.
var gulp = require('gulp');
var del = require('del');
var sourcemaps = require('gulp-sourcemaps');
var sass = require('gulp-sass');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var cleanCSS = require('gulp-clean-css');
var systemjsBuilder = require('gulp-systemjs-builder')
var ts = require('gulp-typescript');
var htmlmin = require('gulp-htmlmin');
/**
* Compile Sass files and keep them in their respective locations.
*/
gulp.task('sass', function () {
console.log('Building Sass files.');
return gulp.src('app/**/*.scss', { base: './' })
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('.'));
});
/**
* Watch Sass files.
*/
gulp.task('sass:watch', function () {
console.log('Watching Sass files.');
gulp.watch('app/**/*.scss', ['sass']);
});
/**
* Compile TypeScript app to JS.
*/
gulp.task('compile:ts', function() {
console.log('Compile TypeScript files into JavaScript files for Angular 4 App.');
var tsProject = ts.createProject('tsconfig.json');
return tsProject.src()
.pipe(sourcemaps.init())
.pipe(tsProject())
.js.pipe(gulp.dest('app'));
});
/**
* Generate systemjs-based bundle (app/app.js).
*/
gulp.task('bundle:app', function() {
console.log('Generate app.js file for Angular 4 App.');
var builder = systemjsBuilder();
builder.loadConfigSync('./system.config.js');
builder.buildStatic('app', 'app/app.js', {
minify: false,
mangle: false
})
.pipe(gulp.dest('portal/app/assets/js'));
})
/**
* Copy and bundle CSS dependencies into one file, vendors.min.css.
*/
gulp.task('bundle:vendorCSS', function() {
console.log('Copy and bundle dependencies into one file, vendors.css.');
return gulp.src([
'node_modules/bootstrap/dist/css/bootstrap.css',
'node_modules/font-awesome/css/font-awesome.min.css',
'node_modules/bootstrap-social/bootstrap-social.css'
])
.pipe(concat('vendors.min.css'))
.pipe(cleanCSS({
level: {
1: {
specialComments: false
}
}
}))
.pipe(gulp.dest('portal/app/assets/css/vendors'));
});
/**
* Copy and bundle CSS dependencies into one file, app.component.min.css.
*/
gulp.task('bundle:appCSS', function() {
console.log('Copy and bundle dependencies into one file, vendors.css.');
return gulp.src([
'app/assets/css/app.component.css'
])
.pipe(concat('app.component.min.css'))
.pipe(cleanCSS({
level: {
1: {
specialComments: false
}
}
}))
.pipe(gulp.dest('portal/app/assets/css'));
});
/**
* Copy and bundle FONT dependencies into one file, vendors.css.
*/
gulp.task('bundle:vendorFONT', function() {
console.log('Copy font dependencies to Angular 4 App\'s portal directory.');
return gulp.src([
'node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.eot*',
'node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.svg*',
'node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf*',
'node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff*',
'node_modules/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2*',
'node_modules/font-awesome/fonts/fontawesome-webfont.ttf*',
'node_modules/font-awesome/fonts/fontawesome-webfont.woff*',
'node_modules/font-awesome/fonts/fontawesome-webfont.woff2*'
])
.pipe(gulp.dest('portal/app/assets/css/fonts'));
});
/**
* Copy and bundle JAVASCRIPT dependencies into one file, vendors.js.
*/
gulp.task('bundle:polyfillsJS', function() {
console.log('Copy and bundle dependencies into one file, polyfills.js.');
return gulp.src([
'node_modules/core-js/client/shim.min.js',
'node_modules/zone.js/dist/zone.js',
'node_modules/reflect-metadata/Reflect.js',
'node_modules/systemjs/dist/system.src.js'
])
.pipe(concat('polyfills.js'))
.pipe(gulp.dest('portal/app/assets/js/polyfills'));
});
/**
* Copy dependencies loaded from SystemJS into portal directory.
*/
gulp.task('copy:vendorJS', function () {
console.log('Copy 3rd party dependencies loaded from SystemJS to Angular 4 App\'s portal directory.');
return gulp.src([
'@angular/common/**',
'@angular/compiler/**',
'@angular/core/**',
'@angular/forms/**',
'@angular/http/**',
'@angular/platform-browser/**',
'@angular/platform-browser-dynamic/**',
'@angular/router/**',
'@ngx-translate/core/**',
'@ngx-translate/http-loader/**',
'@types/highcharts/**',
'angular2-highcharts/**',
'animate.css/**',
'bootstrap/**',
'bootstrap-daterangepicker/**',
'bootstrap-social/**',
'core-js/**',
'font-awesome/**',
'highcharts/**',
'jquery/**',
'jquery-slimscroll/**',
'lodash/**',
'moment/**',
"ng2-breadcrumb/**",
'ng2-daterangepicker/**',
'ngx-bootstrap/**',
'ngx-infinite-scroll/bundles/**',
'reflect-metadata/**',
'rxjs/**',
'systemjs/**',
'zone.js/**'
], { cwd: 'node_modules/**' }) /* Glob required here. */
.pipe(gulp.dest('portal/app/assets/js/vendors'));
});
/**
* Get the LOWER ENVIRONMENT index.html file to the root of the portal directory.
*/
gulp.task('index-lower', function(){
console.log('Get LOWER ENVIRONMENT index.html file to the root of Angular 4 App\'s portal directory.');
return gulp.src(['static_lower/index.html'])
.pipe(gulp.dest('portal'));
});
/**
* Copy the LOWER ENVIRONMENT app core files to the portal directory.
*/
gulp.task('core-lower', ['index-lower'], function(){
console.log('Copy LOWER ENVIRONMENT core application files to the root of Angular 4 App\'s portal directory.');
return gulp.src(['app/**', '!app/**/*.ts', '!app/**/*.scss'])
.pipe(gulp.dest('portal/app'));
});
/**
* Copy node server to portal directory.
*/
gulp.task('server', function () {
console.log('Copy server files to the root of Angular 4 App\'s portal directory.');
return gulp.src(['index.js', 'package.json'], { cwd: 'server/**' })
.pipe(gulp.dest('portal'));
});
/**
* Perform all LOWER ENVIRONMENT tasks at once.
*/
gulp.task('all-lower', ['sass', 'bundle:app', 'bundle:vendorCSS', 'bundle:appCSS', 'bundle:vendorFONT', 'bundle:polyfillsJS', 'copy:vendorJS', 'compile:ts', 'core-lower', 'index-lower', 'server']);
/**
* Bundle LOWER ENVIRONMENT dependencies and app into one file (app.bundle.js).
*/
gulp.task('bundle-lower', ['all-lower'], function() {
console.log('Copy and bundle LOWER ENVIRONMENT JavaScript dependencies into one file, app.bundle.js then drop it into Angular 4 App\'s portal directory.');
return gulp.src([
'portal/app/assets/js/polyfills/polyfills.js',
'portal/app/assets/js/app/app.js'
])
.pipe(concat('app.bundle.min.js'))
.pipe(uglify())
.pipe(gulp.dest('portal/app/assets/js'));
});
/**
* Minify HTML task.
* (filesToCopy is intentionally an empty array in this StackOverflow Question - you don't need a list of html files do you?)
*/
gulp.task('buildmini', function() {
console.log('Minify portal directory\'s html components.');
var filesToCopy = [
];
return gulp.src(filesToCopy, {base: './'})
.pipe(htmlmin({
collapseWhitespace: true,
caseSensitive: true
}))
.pipe(gulp.dest('./'));
});
/**
* Remove portal directory.
*/
gulp.task('clean', function (cb) {
console.log('Removing /portal directory.');
return del(['portal'], cb);
});
system.config.js:
(function (global) {
System.config({
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
// our app is within the app directory
app: 'app',
// angular bundles, inside of node_modules
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
'@angular/common/http': 'node_modules/@angular/common/bundles/common-http.umd.js',
'@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
'@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
'@angular/http': 'npm:@angular/http/bundles/http.umd.js',
'@angular/router': 'npm:@angular/router/bundles/router.umd.js',
'@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
// other libraries, inside of node_modules
'jquery': 'npm:jquery/dist/jquery.js',
'bootstrap': 'npm:bootstrap/dist/js/bootstrap.min.js',
'@ngx-translate/core': 'npm:@ngx-translate/core/bundles/core.umd.js',
'@ngx-translate/http-loader': 'npm:@ngx-translate/http-loader/bundles/http-loader.umd.js',
'rxjs': 'npm:rxjs',
'ngx-infinite-scroll': 'npm:ngx-infinite-scroll/bundles/ngx-infinite-scroll.umd.js',
'tslib': 'npm:tslib/tslib.js',
// charting frameworks
'angular2-highcharts': 'npm:angular2-highcharts',
'highcharts': 'npm:highcharts',
'highcharts/noData': 'npm:highcharts/modules/no-data-to-display.src.js',
'moment': 'npm:moment/moment.js',
'ngx-bootstrap': 'npm:ngx-bootstrap',
'bootstrap-daterangepicker': 'npm:bootstrap-daterangepicker/daterangepicker.js',
'ng2-breadcrumb': 'npm:ng2-breadcrumb',
'ng2-daterangepicker': 'npm:ng2-daterangepicker'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
app: {
main: './main.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
},
highcharts: {
main: './highcharts.js',
defaultExtension: 'js'
},
'angular2-highcharts': {
main: './index.js',
defaultExtension: 'js'
},
'ngx-bootstrap': {
format: 'cjs',
main: 'bundles/ngx-bootstrap.umd.js',
defaultExtension: 'js'
},
'ng2-breadcrumb': {
main: './ng2-breadcrumb.js',
defaultExtension: 'js'
},
'ng2-daterangepicker': {
main: 'index',
defaultExtension: 'js'
}
}
});
})(this);
angular 4 package.json:
{
"name": "angular4-web-app",
"version": "1.0.0",
"author": "Mark",
"description": "Angular 4 Web App on SystemJS",
"homepage": "https://fakehomepage.com",
"scripts": {
"start": "tsc && concurrently \"tsc -w\" \"lite-server\" \"gulp sass\" \"gulp sass:watch\" ",
"start:dev": "copy \"environment_dev.ts\" \"./app/shared/environment/global.constants.ts\" && npm run start",
"start:qa": "copy \"environment_qa.ts\" \"./app/shared/environment/global.constants.ts\" && npm run start",
"start:prod": "copy \"environment_prod.ts\" \"./app/shared/environment/global.constants.ts\" && npm run start",
"tsc": "tsc",
"tsc:w": "tsc -w",
"lint": "tslint ./app/**/*.ts -t verbose",
"lite": "lite-server",
"sass": "gulp sass",
"sass:watch": "gulp sass:watch",
"build:dev": "copy \"environment_dev.ts\" \"./app/shared/environment/global.constants.ts\" && gulp bundle-lower",
"build:qa": "copy \"environment_qa.ts\" \"./app/shared/environment/global.constants.ts\" && gulp bundle-lower",
"build:prod": "copy \"environment_prod.ts\" \"./app/shared/environment/global.constants.ts\" && gulp bundle-prod",
"final": "gulp buildmini",
"destroy": "gulp clean"
},
"license": "ISC",
"dependencies": {
"@angular/common": "4.4.7",
"@angular/compiler": "4.4.7",
"@angular/core": "4.4.7",
"@angular/forms": "4.4.7",
"@angular/http": "4.4.7",
"@angular/platform-browser": "4.4.7",
"@angular/platform-browser-dynamic": "4.4.7",
"@angular/router": "4.4.7",
"@ngx-translate/core": "^6.0.1",
"@ngx-translate/http-loader": "0.0.3",
"@types/highcharts": "^4.2.57",
"angular2-highcharts": "^0.5.5",
"animate.css": "^3.5.2",
"bootstrap": "^3.4.1",
"bootstrap-social": "^5.1.1",
"core-js": "^2.4.1",
"font-awesome": "~4.7.0",
"gulp": "^3.9.1",
"gulp-htmlmin": "^5.0.1",
"highcharts": "^5.0.12",
"jquery": "^3.4.1",
"jquery-slimscroll": "^1.3.8",
"lodash": "^4.17.15",
"moment": "^2.18.1",
"ng2-breadcrumb": "^0.5.14",
"ng2-daterangepicker": "^2.0.8",
"ngx-bootstrap": "^2.0.5",
"ngx-infinite-scroll": "^0.5.1",
"reflect-metadata": "^0.1.3",
"rxjs": "5.4.2",
"systemjs": "0.19.27",
"zone.js": "^0.6.23"
},
"devDependencies": {
"@types/node": "^6.0.60",
"concurrently": "^3.1.0",
"connect-history-api-fallback": "^1.3.0",
"del": "^2.2.2",
"gulp-clean-css": "^3.9.0",
"gulp-concat": "^2.6.1",
"gulp-sass": "^3.1.0",
"gulp-sourcemaps": "^2.6.0",
"gulp-systemjs-builder": "^0.15.0",
"gulp-typescript": "^3.2.1",
"gulp-uglify": "^3.0.0",
"lite-server": "^2.3.0",
"tslint": "^3.7.4",
"typescript": "^2.2.2"
},
"repository": {
"type": "git",
"url": "https://bitbucket.org/mark/angular4-web-app.git"
}
}
在您的配置文件中,例如webpack config或Babel,您将需要使用与操作系统无关的方法来查找文件,因为:
Windows使用\
,其他所有内容使用/
因此需要Node的内置path
模块
const path = require('path')
并且在您的配置文件中使用path
和__dirname
// "target": "./dist"
"target": path(__dirname, '/dist')
webpack的证据:
https://webpack.js.org/configuration/
(尽管有问题的不只是webpack)