Skip to content
This repository was archived by the owner on Aug 7, 2021. It is now read-only.

feat: angular 5 #328

Merged
merged 12 commits into from
Dec 6, 2017
Merged

feat: angular 5 #328

merged 12 commits into from
Dec 6, 2017

Conversation

PanayotCankov
Copy link
Contributor

@PanayotCankov PanayotCankov commented Nov 27, 2017

This PR addresses several issues and introduces some new features.

  1. Angular5 support
  2. Adds support for CSS files to be added through the css-loader for vanilla apps and the app.css (the nativescript-css-loader is now obsolete)
  3. Adds the app.css in the snapshot for Android, it is registered in the vendor.js so the snapshot generator can load, and parse the NativeScript theme
  4. Adds the PlatformFSPlugin to map files:
    • Filter alien files (e. g. when building for Android will filter .ios. files)
    • Rename platform specific files (e. g. when building for android *.android. will be renamed to *.)
    • Handles watching for platform specific files (e. g. for Android when watching for component.ts will also watch for component.android.ts)
  5. Should bump the version to 0.9.0
  6. Adds demo apps that feature most of the supported features in webpack and have automation tests on top
  7. Adds the WatchStateLoggerPlugin to do IPC with the CLI and notify for watch state changes
  8. Options! Webpack options are passed through the CLI with tns run ios|android --bundle --env.*
    • --env.snapshot enables snapshot for android
    • --env.uglify enables uglification and minification
    • --env.report creates the report folder with chunk stats
    • --env.aot for angular, enables the Angular ahead-of-time compilation

For Angular5

  1. Implements a NativeScriptAngularCompilerPlugin that uses the new AngularCompilerPlugin from @angular/webpack
    The new AngularCompilerPlugin creates a TypeScript CompilerHost under the hood and uses it for webpack compiler.inputFileSystem and compiler.watchFileSystem, it also compiles CSS and HTML resources. The NativeScriptAngularCompilerPlugin extends the AngularCompilerPlugin to handle platform specific resource resolution and resolving compiler modules in the CompilerHost. Then the PlatformFSPlugin's effect is applied on top of the AngularCompilerPlugin's FS so webpack can work with the platform specific files seemlesly.
  2. webpack --watch watch is able to recompile in under 2 sec, but is not yet integrated in the CLI

For JavaScript and TypeScript apps

  1. Adds the PlatformFSPlugin
  2. Enumerates the page.* files in the app folder and registers them in the NativeScript framework using dynamic webpack require contexts, it is then registered in the global.registerWebpackModule so the modules can load .js, .css, .sass, .xml, etc. files, dens no longer need to list these files manually

Breaking Changes

I am sorry guys, but the way this PR works makes a lot of sense (snapshotting the theme because we can, using the css-loader because we can, etc.) but that also introduces some annoying breaking changes:

  • The theme should now be required using leading tilde without slash:
    @import '~nativescript-theme-core/css/core.light.css';.
    that's how the css-loader loads css files from the node_modules.
  • The routes loadChildren best be absolute paths, System.import we use now has no support for referrer so the paths provided to loadChildren better be non-relative, so:
    loadChildren: "./details/ninja.module#NinjaModule" in the ninjas folder becomes:
    loadChildren: "~/ninjas/details/ninja.module#NinjaModule".
    in case you still want to use tns run ios|android without web pack.
  • The tsconfig.json, for the love of tilde, better get paths like:
        "paths": {
            "~/*": [
                "app/*"
            ],
            "*": [
                "./node_modules/tns-core-modules/*",
                "./node_modules/*"
            ]
        }
  • When bundled with webpack, webpack uses numbers for module.id and Angular throws number is not a string kind of errors. Replace all occurrences of moduleId: module.id with moduleId: __filename. This works well in {N} context, __filename is almost the same as module.id with the little difference that it has the .js extension, while webpack replaces occurrences of __filename with paths relative to the app folder.

Instead of relying on npm scripts, rely on hooks so that certain parts of the prepare chain can be overriden.
Do not skip moving `App_Resources` directory, as CLI expects it to be present in platforms and will take care of the resources inside.

chore(deps): unpin nativescript-hook version

enable webpack builds in debug and optional snapshot

feat: support for Angular 5

- add NativeScriptAngularCompilerPlugin that extends AngularCompilerPlugin

BREAKING CHANGES

NativeScriptAngularCompilerPlugin must be used instead of AotPlugin in your webpack configuration from now on. You can regenerate the webpack configuration if you haven't made changes to it by running "./node_modules/.bin/update-ns-webpack --configs". ...

Implement NativeScriptAngularCompilerPlugin and integrate the PlatformFSPlugin

.js .map.js and .d.ts files don't have to stay in source control, they will be generated on prepare

Make prepare script to tsc, and ignore .ts artifacts from source control

Remove the prepare scripts that create templates/webpack.*.js

Make the webpack config work for angular, typescript and javascript WIP

chore: update added versions

Add Angular and JavaScript apps for tests

Add demo/AngularApp, demo/JavaScriptApp in wip

chore: remove dependency to @angular/animations as it's not used

feat(demo-ng): add lazy loaded modules

Add scss and platform specific files to the JavaScriptApp demo

Make JavaScriptApp work with css and scss, bundle all .js, .css and .scss files

test(AngularApp): add configs, dependencies and samples

Add some testable rectangles for the app so we can ensure CSS and SCSS work

Fix a minor bug in the angular webpack plugin

Added a TypeScript project and configured the TypeScript webpack config

test(AngularApp): add tests and images

Map the watchFileSystem, seems to work 'decently' now...

Map timestamps so platform specific files dont get rebuild with every change

Add IPC notifications for CLI watch

Adding IPC channel without watch made the proccess hang

filter for watcher was mapping absolute paths to basenames
vchimev and others added 2 commits November 29, 2017 16:24
Fix `cwd` parameter name. Remove `shell: true` becuase it causes issues on windows.
@@ -225,7 +225,7 @@ function spawnChildProcess(command, ...args) {

const childProcess = spawn(command, escapedArgs, {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should spawn tns run ios|android --bunlde ... and obsolete the implementation.

@@ -0,0 +1,8 @@
var compiler = require('./compiler');
module.exports = function($logger) {
var webpackProcess = compiler.getWebpackProcess();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const instead of vars

@@ -71,8 +7,9 @@ module.exports = function ($mobileHelper, $projectData, hookArgs) {
const config = {
env,
platform,
bundle: appFilesUpdaterOptions.bundle
bundle: appFilesUpdaterOptions.bundle,
watch: false
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are preparing the nativescript-dev-webpack for watch but it is not there yet.

lib/compiler.js Outdated
}

// TODO: Read from CLI options...
const { watch } = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Delete, move the comment.

lib/compiler.js Outdated
});

function resolveOnWebpackCompilationComplete(message) {
if (message === "Webpack compilation complete. Watching for file changes.") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract constants


if (config.watch) {
childProcess.on("message", resolveOnWebpackCompilationComplete);
if (webpackProcess) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mitko-Kerezov
Probably we will not throw here, but we will figure it out when it is integrated in the CLI,


export const AngularCompilerPlugin: typeof ngToolsWebpack.AngularCompilerPlugin = appNgToolsWebpack.AngularCompilerPlugin;

export type NativeScriptAngularCompilerPluginOptions = ngToolsWebpack.AngularCompilerPluginOptions & { platformOptions?: PlatformFSPluginOptions };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the fuck did I wrote?

export interface NativeScriptAngularCompilerPluginOptions extends ngToolsWebpack.AngularCompilerPluginOptions {
    platformOptions?: PlatformFSPluginOptions;
}

}
};
this.__compilerHost.resourceNameToFileName = function(file, relativeTo) {
const parsed= path.parse(file);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space

getCompiledFile(this: NativeScriptAngularCompilerPlugin, file: string): CompiledFile {
try {
if (this.platform) {
const parsed= path.parse(file);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space


public apply(compiler) {
this.context = compiler.context;
compiler.inputFileSystem = mapFileSystem({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: We will need to augment the watch file system.

const alienPlatforms = platforms.filter(p => p !== platform);
const alienPlatformFilters = alienPlatforms.map(platform => ({
endsWithSuffix: `.${platform}`,
contains: `.${platform}.`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may fire false positives on:
component.android.ts // ok
component.android.myapp.ts // not-ok


const trimPlatformSuffix = file => {
const {dir, name, ext} = parseFile(file);
if (ext === currentPlatformExt) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just don't


function platformSpecificFile(file: string): string {
const {dir, name, ext} = parseFile(file);
const platformFilePath = join(dir, name + ("." + platform) + ext);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template string...

// SASS support
{ test: /\.scss$/, use: ["raw-loader", "resolve-url-loader", "sass-loader"] },
// Compile TypeScript files with ahead-of-time compiler.
{ test: /.ts$/, loader: "@ngtools/webpack" },
Copy link
Contributor Author

@PanayotCankov PanayotCankov Nov 30, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea if this should be used at all.
My guess is when component.ts module is resolved by webpack, it will get this loader to call getCompilerFile on the AngularCompilerPlugin.

@vchimev
Copy link
Contributor

vchimev commented Dec 1, 2017

typescript-android

@vchimev
Copy link
Contributor

vchimev commented Dec 1, 2017

typescript-ios

@vchimev vchimev changed the title Angular5 feat: angular 5 Dec 5, 2017
@sis0k0
Copy link
Contributor

sis0k0 commented Dec 5, 2017

Heya! Just a few question about the PR :).

The routes loadChildren best be absolute paths, System.import we use now has no support for referrer so the paths provided to loadChildren better be non-relative, so:
loadChildren: "./details/ninja.module#NinjaModule" in the ninjas folder becomes:
loadChildren: "~/ninjas/details/ninja.module#NinjaModule".
in case you still want to use tns run ios|android without web pack.
The tsconfig.json, for the love of tilde, better get paths like:
        "paths": {
            "~/*": [
                "app/*"
            ],
            "*": [
                "./node_modules/tns-core-modules/*",
                "./node_modules/*"
            ]
        }

Does that mean we can use "app/.../something" for specifying absolute routes or there is a particular reason for mapping 'tilde' (~) to 'app'?

When bundled with webpack, webpack uses numbers for module.id and Angular throws number is not a string kind of errors. Replace all occurrences of moduleId: module.id with moduleId: __filename. This works well in {N} context, __filename is almost the same as module.id with the little difference that it has the .js extension, while webpack replaces occurrences of __filename with paths relative to the app folder.

Do we still need the moduleId when building without webpack now, when we're reusing the SystemJsModuleLoader? If we don't, do you think it's a good idea to have a plugin that adds the moduleId: __filename node dynamically to components as part of the webpack build process?

@PanayotCankov
Copy link
Contributor Author

I am not sure actually, we currently have to support three configurations:

  1. tns run android
  2. tns run android --bundle
  3. tns run android --bundle --env.out
    And the above is the only setup that work in all of them. I thing moduleId is obsolete but there was a reason it is still necessary. This article is helpful: https://angular.io/guide/change-log (All mention of moduleId removed. "Component relative paths" guide deleted)

I will double check what's the state with the paths in all of them.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants