Compiling Angular 2 Ahead-of-Time using gulp and typescript

Angular 2 rc 6 implemented in Typescript 2.0.2

I'm currently exploring Ahead-of-Time compilation as described here. It appears to be straightforward:

  • Use ngc instead of the Typescript compiler to create .ngfactory.ts files
  • Substitute
    platformBrowserDynamic().bootstrapModule()
    with
    platformBrowser().bootstrapModuleFactory()

The challenge I'm facing is how to implement the first step within my existing setup. I rely on gulp-typescript 2.13.6 for converting TypeScript to JavaScript.

gulpfile.js

var ts = require('gulp-typescript');
var tsProject = ts.createProject('tsconfig.json', {
    //Utilize NPM-installed TS version instead of gulp-typescript's default
    typescript: require('typescript')
});
gulp.task('build-ts', function () {
    return gulp.src(appDev + '**/*.ts')
        .pipe(ts(tsProject))
        .pipe(gulp.dest(appProd));
});

So my query is; how can I incorporate these guidelines into my current tooling? How do I instruct gulp-typescript to utilize the Angular Compiler? I've experimented with:

var tsProject = ts.createProject('tsconfig.json', {
    typescript: require('@angular/compiler') // or '@angular/compiler-cli'
});

This approach results in errors without triggering ngc. I also attempted:

var tsProject = ts.createProject('tsconfig.json', {
    typescript: require('./node_modules/.bin/ngc')
});

While this does execute ngc, it promptly produces an error message:

SyntaxError: Unexpected string at ngc:2: basedir=$(dirname "$(echo "$0" | sed -e 's,\,/,g')")

I suspect that the issue arises from not passing a source directory to ngc (the correct command being ngc -p path/to/project)

In essence, is there a means to use gulp-typescript for streamlining the build process? (generating .ngfactory.ts files and then compiling everything to JavaScript)

Answer №1

It seems that the issue with the typescript: require(..) not working is due to gulp-typescript looking for either something named typescript or attempting to execute the command tsc. Since the angular compiler command is actually ngc, it fails to locate it.

If you have a simple project that just needs to be compiled, you can directly run the command from gulp like this:

var exec = require('child_process').exec;

gulp.task('task', function (cb) {
  exec('ngc -p "<path to your tsconfig.json>"', function (err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
    cb(err);
  });
});

Ensure that your tsconfig.json is properly configured, with additional options mentioned by Google in their documentation here, under the Configuration section.

If you require the more advanced features provided by gulp-typescript package, you may need to implement them yourself or wait for someone else to do so.

Answer №2

After struggling to make it work, I found great guidance in William Gilmour's solution.

I took it a step further by customizing it to accommodate a local ngc installation (similar to the Angular 2 illustration that uses the one located in node_modules/.bin), ensuring compatibility with both Linux and Windows operating systems:

var exec = require('child_process').exec;
var os = require('os');

gulp.task('build-ts', function (cb) {

    var cmd = os.platform() === 'win32' ? 
        'node_modules\\.bin\\ngc' : './node_modules/.bin/ngc';

    exec(cmd, function (err, stdout, stderr) {
        console.log(stdout);
        console.log(stderr);
        cb(err);
    });
});

Answer №3

Here is the gulpfile I am currently using for Ahead-Of-Time (AOT) compilation with angular 2, which works across different platforms:

//jshint node:true
//jshint esversion: 6
'use strict';

...

// function to run ngc and tree shaking tasks
const execute = (cmd, callback, options) => {
        process.stdout.write(stdout);
        process.stdout.write(stderr);
        callback(err);
    });
};


gulp.task('ngc', ['css', 'html', 'ts'], cb => {
    let cmd  = 'node_modules/.bin/ngc -p tsconfig-aot.json';
    if (isWin) {
        cmd  = '"node_modules/.bin/ngc" -p tsconfig-aot.json';
    }
    return execute(cmd, cb);
});

You can view the full example of the Tour of Heroes (ToH) with gulp.js on my github repository: ng2-heroes-gulp

While this serves as a temporary solution, I plan to implement the gulp-ngc plugin for a more sustainable approach in the long term.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Cannot find a compatible version for Angular2 Installation

Having trouble installing Angular 2. I followed the quickstart guide but still can't get it to install/start. npm ERR! Windows_NT 6.2.9200 npm ERR! argv C:....\\npm\\node_modules\\npm\\bin\\npm-cli.js ...

Upgrading to CRA 2.0 with TypeScript caused my tsconfig.json file to be overridden because of a limitation in the

Struggling to set up tailwindcss with typescript in a fresh CRA 2.0 (specifically 2.1.2). Having trouble overriding the "isolatedModules": true flag as CRA keeps overwriting it. Tried changing the export style from modules.export and setting the config t ...

Implementing multer diskStorage with Typescript

I'm currently in the process of converting a node.js server to TypeScript. Here is what my function looks like in Node: const storage = multer.diskStorage({ destination: function (req, file, cb) { const dir = './uploads/'; ...

Error: Request for resolution of all parameters for SignupComponent failed: ([object Object], ?). Occurred at the syntaxError in compiler.js:2175

Could someone assist me in resolving this issue? signup.component.html <main role="main" class="container> <h1 class="mt-5">&nbsp;</h1> <h5 class="mt-5 ">Create Account</h5> <br/> <div class="loa ...

What is the best way to link assets within an Angular custom element (Web Components)?

After successfully creating a web component and referencing an image from my asset folder, everything was running smoothly on my local environment. However, when I published my custom element to Firebase hosting, I encountered some issues. When trying to ...

Setting default values in Angular dropdown select using TypeScript

How can a default value be set in a Select element? I am attempting to create a time dropdown select with multiple options. Currently, the selectedTimeOption variable correctly identifies if an option is chosen from the dropdown, but it cannot detect a va ...

Creating Unique Layouts for Specific Routes in Next.js App Router

Issue with Layout Configuration I am facing a challenge in creating a unique layout for the /api/auth/* routes without including the components CustomNavbar and Footer from the main RootLayout. Despite my attempts, the main layout continues to be displaye ...

What are the steps to configure Angular to run with https instead of the default http protocol?

Typically, Angular applications run on http by default (for example, on http://localhost:4200). Is there a way to switch it from http to https? ...

What is the process of combining two states in Angular?

Having a state defined as: export interface ChatMessagesState { messages: Message[] | null; chatId: string; } and receiving data in the websocket like: newMessages: Message[] = [ { text: 'Hello', chatId: '100' }, { text ...

Error in VueJS: A linting issue is occurring with the message "JSX element type 'X' does not have any construct or call signatures" when attempting to globally register components

Everything seems to be in working order. I have successfully utilized the components and managed to build the app without encountering any issues. However, my text editor (VS Code) continues to throw a linting error even after attempting to register my own ...

The Angular Library seems to be malfunctioning as it does not execute the ngOnInit

I've been following the instructions from Angular CLI 6 to create a library, which can be found here. So far, I've successfully created and built my library. It includes a Component that I'm using for the UI and has an HTML selector. @Compo ...

Accessing dynamically generated text from an li element in Angular by transferring it from the HTML to the TypeScript component

Can you assist me with this issue? Below is the code snippet: Xpressions Total ={{response.total}} clear </div> <div class="exResult"> <ul> <li *ngFor='let item of response.data'> {{item.ph ...

Attempting to integrate TypeScript into my webpack-generated bundle

Despite specifying loader: 'ts', I keep encountering this error: 50% 4/6 build modulesModuleParseError: Module parse failed: /home/rob/git/repo/src/app/container.entry.ts Unexpected token (16:70) You may need an appropriate loader to handle thi ...

Vue-test-utils encounters a `SyntaxError` when importing with Jest, throwing the error message "Cannot use import statement outside a module"

I'm facing an issue with my NuxtJS setup using Jest and Typescript. I can't seem to get my test to run properly due to an exception. Details: /home/xetra11/development/myapp/test/Navigation.spec.js:1 ({"Object.<anonymous>&quo ...

Trouble encountered with Axios post request in TypeScript

Currently, I am in the process of integrating TypeScript into my project and while working with Axios for a post request, I encountered an issue. The scenario is that I need to send email, first name, last name, and password in my post request, and expect ...

Leveraging jQuery within an Angular environment with TypeScript and Webpack

In my Angular (v2) project that utilizes TypeScript and Webpack, I initially used a starter project for seed. However, the configuration has been significantly modified to the point where referencing the source is irrelevant. Recently, I decided to incorp ...

Unable to utilize injection without the presence of an observer

Currently, I am working with typed React (TSX) and mobx for managing state. I have successfully created a component that uses both observer and inject decorators. However, I am struggling to create a component that only uses inject without observer. This ...

Guide to creating a disappearing and reappearing navigation bar in Angular2 when scrolling

I am attempting to recreate the functionality of a scroll-triggered header hiding feature implemented in Angular 2. Below is the code snippet I'm working with: // Hide Header on on scroll down var didScroll; var lastScrollTop = 0; var delta = 5; va ...

Animation on React child component disappears when re-rendered

My React application utilizes Material UI with a component (let's call it DateSelector) as shown below, slightly altered for demonstration purposes. https://i.sstatic.net/RlPZa.gif Material UI provides animations for clicks and interactions within i ...

Encountering challenges while npm installing and deploying on Heroku platform

Keep encountering this persistent error. Installing node modules npm ERR! code ERESOLVE npm ERR! ERESOLVE could not resolve npm ERR! npm ERR! While trying to resolve: @angular-devkit/<a href="/cdn-cgi/l/email-protection" cla ...