openmarco / gulp-systemjs-builder

A tiny wrapper around SystemJS builder .bundle and .buildStatic methods
MIT License
1 stars 7 forks source link

Error on fetch for app/main.js, Error: ENOENT: no such file or directory, open #9

Open marklreyes opened 4 years ago

marklreyes commented 4 years ago

Looks like someone else fell through this same problem too - however, no solution. See Github Issue #5.

I also placed this issue on StackOverflow as well.

A specific set of GulpJS errors are surfacing when trying to build out an Angular 4 Web App with SystemJS.

What's odd is that usually this build script works. There were no edits to the GulpJS or SystemJS file. I'm curious if something in the node/npm ecosystem changes this assumption. At any rate, your thoughts on a fix would be appreciated.

My Windows 10 machine is currently installed with Node version 10.14.0 and npm version of 6.9.0.

When executing npm run build:dev The errors from Gulp show in the terminal as:

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'

To be clear, the above file being main.js does truly exist in the file system.

Gulp continues, and the remainder of the build completes. But when testing out the final build, the app doesn't load and this asset is missing from the final build:

Noticeably missing from the final build artifact: app/assets/js/app/app.js

20200211_wtf_vscode

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"
  }
}
lancegiles commented 4 years ago

Did you ever find a solution to this? I too am having this issue.

marklreyes commented 4 years ago

Sorry, @lancegiles I did not. I can only speculate that it happens when trying Gulp scripts with Windows machine. I couldn't afford any more time to hammer through this problem so I pivoted to running builds in OSX. I swayed in this direction based on some comments from people who replied to me on StackOverflow. So far so good with that choice.

lancegiles commented 4 years ago

Understood and thanks! I've sunk 2 full days into this so far so I may be headed in that direction too!

marklreyes commented 4 years ago

Yes, that's too much time to invest. Cease fire and build from OSX. You'll have to modify the start command. Recall, OSX uses cp not copy.

lancegiles commented 4 years ago

Appreciate the tip!

lancegiles commented 4 years ago

Holy crap I found it! So in my case one of my folders had a space in it like this "MelissaG Photos" When the gulp tried to process the text it replaced that with a %20 inside the filepath. I then received the error.

Removing that space solved the problem and allowed the bundle to go through!

marklreyes commented 4 years ago

What node module had that?

lancegiles commented 4 years ago

it was the 'plugin-text'