Skip to content

Angular 9 #2060

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
simkepal opened this issue Nov 9, 2019 · 37 comments · Fixed by #2169
Closed

Angular 9 #2060

simkepal opened this issue Nov 9, 2019 · 37 comments · Fixed by #2169
Labels

Comments

@simkepal
Copy link

simkepal commented Nov 9, 2019

Hello,

I have a question: Is there already something to test out NativeScript with Angular 9? I am building an app for web, which will go out in December and thinking about to have also mobile app.

Thanks for answer!

@VladimirAmiorkov
Copy link
Contributor

VladimirAmiorkov commented Nov 12, 2019

Hi @simkepal ,

Thank you for the interest of Angular 9 and its integration in NativeScript. We have been working closely with the Angular team in order to make sure that the Ivy feature of the Angular 9.0.0 release will be available in NativeScript with as little requirements as possible. While the story about Ivy is still not fully functioning in NativeScript we have resolved all other changes and compatibility requirement that come with Angular 9.0.0.

You can test an early version of the nativescript-angular package that is build agains the 9.0.0-rc.1 version of Angular by using the ivy tag of the package which is now available in npm.

As already mentioned the Ivy functionality is still in development and is currently not working so you will have to disable it. After installing the nativescript-angular@ivy package and running the dependencies update script (./node_modules/.bin/update-app-ng-deps) because Angular 9.0.0 comes with Ivy enabled by default you have to disable it by placing this in the app's tsconfig.json:

"angularCompilerOptions": {
      "enableIvy": false
}

Note that this is an very early "preview" of the nativescript-angular package integration with Angular 9.0.0, if you notice any issue please report them here.

@samirotiv
Copy link

Hi, thanks for your work. Could you tell me when Angular 9 support for Nativescript is expected? Angular 9 has been officially released.

@flodaniel
Copy link

I am also looking forward to Angular 9. Especially components such as the google maps component will be great too use: https://github.com/angular/components/tree/master/src/google-maps

@BenSjoberg
Copy link

To me the most exciting thing about Angular 9 is it supports TypeScript 3.7, with optional chaining. Looking forward to cleaning up a bunch of code as soon as this is ready. 😀

@MattRiddell
Copy link

Crap upgraded angular on a large project with a web site and an app and the Nativescript side is broken.

Any ideas on when NativeScript will work again?

@MattRiddell
Copy link

Ok cool after actually RTFM I can confirm it is working with the following steps:

npm i nativescript-angular@ivy  
./node_modules/.bin/update-app-ng-deps
npm i

@plackowski
Copy link

plackowski commented Feb 12, 2020

Unfortunately my application doesn't work after migration to Angular 9. The web application works well, but in ns app I have a lot of bugs during the launch.

I tried to create new empty code-sharing project and then migrating to ng 9 with the same results :(. Finally I can't migrate my web app to ng 9 because of that.

@vinckobb
Copy link

vinckobb commented Feb 17, 2020

I've tried to upgrade Nativescript Hello world application to angular 9 with nativescript-angular@ivy but I've ended with error

ERROR in Symbol TextValueAccessor declared in C:/DATA/Repo/sandbox/nativescript-ivy/node_modules/@nativescript/angular/forms/value-accessors/text-value-accessor.js is not exported from C:/DATA/Repo/sandbox/nativescript-ivy/node_modules/@nativescript/angular/forms/value-accessors/text-value-accessor (import into C:/DATA/Repo/sandbox/nativescript-ivy/node_modules/@nativescript/angular/forms/forms.module.js)

Does anybody know what might be the problem?

@NathanWalker
Copy link
Contributor

@vinckobb @Arystosedes @BenSjoberg @samirotiv @Firetrip Give this a shot:
#2124 (comment)

@vinckobb
Copy link

@NathanWalker I've tried your PR but still same error. Created repo with your version of nativescript angular so you can try https://github.com/vinckobb/nativescript-angular-demo

@NathanWalker
Copy link
Contributor

NathanWalker commented Feb 18, 2020

Thanks @vinckobb that's super helpful! I'll give it shot and see if some subtle project setup issue may be getting in way with what you got there. I'll have chance to take peek on Wednesday.

@NathanWalker
Copy link
Contributor

@vinckobb here ya go: vinckobb/nativescript-angular-demo#1

@vinckobb
Copy link

vinckobb commented Feb 20, 2020

@NathanWalker tried your PR but still same error while compiling with ngcc. I'm using Windows right now so it can be Windows related. I'll try os x in the evening.

So it definitely looks like Windows related problem. It works like a charm on OS X. I'm going check what might be the problem. Thanks a lot @NathanWalker

@NathanWalker
Copy link
Contributor

NathanWalker commented Feb 23, 2020

@vinckobb my guess is likely Windows has issue with the postinstall handling and/or ngcc trying to compile node_modules and runs into path/directory issue possibly. Lemme know if you find what is affecting Windows.

Thanks for letting us know Mac/OS X worked for you 👍

@vinckobb
Copy link

@NathanWalker I had to explicitly list exported names in form/value-accessor to make it work on Windows as you can see in vinckobb@4eb895f

Don't know why I had to do this for this particular index.ts because http-client works without any problems.

@joshcomley
Copy link
Contributor

@vinckobb did you compile your own version of nativescript-angular with this change?

@vinckobb
Copy link

@joshcomley yes I did. I've updated my repo https://github.com/vinckobb/nativescript-angular-demo with compiled version of nativescript-angular that is working on Windows.

You can compile it yourself if you want. Clone or fork nativescript-angular repo, go to nativescript-angular directory and run command npm run pack. It will create .tgz file in dist repo in main directory.

@NathanWalker
Copy link
Contributor

@vinckobb this pr has been updated with your export changes as well:
#2124

@NathanWalker
Copy link
Contributor

NathanWalker commented Mar 2, 2020

@joshcomley @vinckobb for ease I posted the compiled working v9 versions to a repo - these include the fix to exports for windows as well, just set your package.json to the following:

"@nativescript/angular": "https://github.com/nstudio/ns-ng/blob/master/nativescript-angular-9.0.0.tgz?raw=true",
"nativescript-angular": "https://github.com/nstudio/ns-ng/blob/master/nativescript-angular-compat.tgz?raw=true"

Then reference the notes made here regarding tsconfig and other details for Ivy compliance:
#2124 (comment)

@NathanWalker
Copy link
Contributor

@vinckobb i pushed another fix to that PR that may have also been affecting forms and similar to what you had mentioned on windows. With this final adjustment I’m seeing stable Ivy behavior:
35e4864

The latest remote tgz’s provided here have all latest fixes:

"@nativescript/angular": "https://github.com/nstudio/ns-ng/blob/master/nativescript-angular-9.0.0.tgz?raw=true",
"nativescript-angular": "https://github.com/nstudio/ns-ng/blob/master/nativescript-angular-compat.tgz?raw=true"

@iameduardod
Copy link

@NathanWalker any update to support angular v9?

@blankstar85
Copy link

Any Update to this?

@NathanWalker
Copy link
Contributor

All details to use Angular 9 with NativeScript today can be found here: #2124 (comment)

If anyone encounters issue with instructions provided, please post a public repo here and what you are running into and would be happy to help.

@blankstar85
Copy link

@NathanWalker Thanks for the quick comment!!! I'll give it a shot.

@iameduardod
Copy link

An alternative is switching to a framework that already supports v9 https://twitter.com/LiamDeBeasi/status/1261298258506375169

@handelcamilo
Copy link

Hi Guys, I am wondering if the Angular+NativeScript is still in development. I am new to Angular and I liked it a lot, so would be greate if we could use Angular with NativeScript.

@NathanWalker
Copy link
Contributor

Hi @handelcamilo thanks for the comment - the Angular 9 Ivy support in #2124 will be merged and published by no later than Wednesday next week along with some long awaited goodies like true async APP_INITIALIZER support and some nice support for easy animated launch screens given async launch conditions 👍

@handelcamilo
Copy link

Good to know @NathanWalker!! I was afraid because the last change on this project was in February.. This is a very and important project to simply die hheeheh and you are doing a great job! I hope I can help with any time soon. Thanks.

@hrueger
Copy link

hrueger commented May 31, 2020

@NathanWalker is the next release going to support the angular 9 i18n system?

@NathanWalker
Copy link
Contributor

@hrueger I haven't tried their i18n commands yet and the configuration specified in that doc but definitely seems like we could make that work (if it doesn't already). I have often used ngx-translate for all i18n on {N} apps as it's a very solid solution but I definitely think the i18n solution the angular team specifies should be able to work.

@doublechecker
Copy link

$localize seems not to be working. I also cannot find anything regarding nativescript and $localize (or Angular 9 in general). When can we expect a solution as this is really blocking us from migrating our app to NativeScript?

@hrueger
Copy link

hrueger commented Jun 4, 2020

Why is the @nativescript/angular package on npm released with version 9.0.0, but not the nativescript-angular package? This one is still 8.21.0...

@dimitri-bret
Copy link

Why is the @nativescript/angular package on npm released with version 9.0.0, but not the nativescript-angular package? This one is still 8.21.0...

They are the same package. You can switch to @nativescript/angular

@NathanWalker
Copy link
Contributor

@hrueger - @dimitri-bret is correct - nativescript-angular had become just an alias to @nativescript/angular back in the 6.0 release (or maybe earlier?) so you can just use @nativescript/angular now - and in fact all {N} packages will be going fully scoped in 7.0 and you are safe to move to @nativescript/core instead of tns-core-modules right now. If you encounter any issues you can use this webpack.config that adds the aliases to help with any plugins you may use which may still use old style imports (this is a slightly improved webpack.config and will likely soon add some of these adjustments to latest nativescript-dev-webpack plugin - just npm i terser-webpack-plugin --save-dev if you don't have it installed as it's used here 👍 ):

const { join, relative, resolve, sep, dirname } = require('path');

const webpack = require('webpack');
const nsWebpack = require('nativescript-dev-webpack');
const nativescriptTarget = require('nativescript-dev-webpack/nativescript-target');
const {
  nsReplaceBootstrap
} = require('nativescript-dev-webpack/transformers/ns-replace-bootstrap');
const {
  nsReplaceLazyLoader
} = require('nativescript-dev-webpack/transformers/ns-replace-lazy-loader');
const {
  nsSupportHmrNg
} = require('nativescript-dev-webpack/transformers/ns-support-hmr-ng');
const {
  getMainModulePath
} = require('nativescript-dev-webpack/utils/ast-utils');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const {
  NativeScriptWorkerPlugin
} = require('nativescript-worker-loader/NativeScriptWorkerPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const {
  getAngularCompilerPlugin
} = require('nativescript-dev-webpack/plugins/NativeScriptAngularCompilerPlugin');
const hashSalt = Date.now().toString();

module.exports = env => {
  // Add your custom Activities, Services and other Android app components here.
  const appComponents = [
    "@nativescript/core/ui/frame", "@nativescript/core/ui/frame/activity"
  ];

  const platform = env && ((env.android && 'android') || (env.ios && 'ios'));
  if (!platform) {
    throw new Error('You need to provide a target platform!');
  }

  const AngularCompilerPlugin = getAngularCompilerPlugin(platform);
  const projectRoot = __dirname;

  // Default destination inside platforms/<platform>/...
  const dist = resolve(
    projectRoot,
    nsWebpack.getAppPath(platform, projectRoot)
  );

  const {
    // The 'appPath' and 'appResourcesPath' values are fetched from
    // the nsconfig.json configuration file
    // when bundling with `tns run android|ios --bundle`.
    appPath = 'src',
    appResourcesPath = 'App_Resources',

    // You can provide the following flags when running 'tns run android|ios'
    aot, // --env.aot
    snapshot, // --env.snapshot,
    production, // --env.production
    uglify, // --env.uglify
    report, // --env.report
    sourceMap, // --env.sourceMap
    hiddenSourceMap, // --env.hiddenSourceMap
    hmr, // --env.hmr,
    unitTesting, // --env.unitTesting
    verbose, // --env.verbose
    ci, // --env.ci
    snapshotInDocker, // --env.snapshotInDocker
    skipSnapshotTools, // --env.skipSnapshotTools
    compileSnapshot // --env.compileSnapshot
  } = env;

  const useLibs = compileSnapshot;
  const isAnySourceMapEnabled = !!sourceMap || !!hiddenSourceMap;
  const externals = nsWebpack.getConvertedExternals(env.externals);
  const appFullPath = resolve(projectRoot, appPath);
  const appResourcesFullPath = resolve(projectRoot, appResourcesPath);
  const tsConfigName = 'tsconfig.tns.json';
  const entryModule = `${nsWebpack.getEntryModule(appFullPath, platform)}.ts`;
  const entryPath = `.${sep}${entryModule}`;
  const entries = { bundle: entryPath };
  const areCoreModulesExternal =
    Array.isArray(env.externals) &&
    env.externals.some(e => e.indexOf('@nativescript') > -1);
  if (platform === 'ios' && !areCoreModulesExternal) {
    entries['tns_modules/@nativescript/core/inspector_modules'] =
      'inspector_modules';
  }

  const ngCompilerTransformers = [];
  const additionalLazyModuleResources = [];
  if (aot) {
    ngCompilerTransformers.push(nsReplaceBootstrap);
  }

  const copyTargets = [
    { from: { glob: 'assets/**' } },
    { from: { glob: 'fonts/**' } }
  ];

  if (!production) {
    // TIP: you can push in additional copyTargets for development purposes only

    if (hmr) {
      ngCompilerTransformers.push(nsSupportHmrNg);
    }
  }

  // when "@angular/core" is external, it's not included in the bundles. In this way, it will be used
  // directly from node_modules and the Angular modules loader won't be able to resolve the lazy routes
  // fixes https://github.com/NativeScript/nativescript-cli/issues/4024
  if (env.externals && env.externals.indexOf('@angular/core') > -1) {
    const appModuleRelativePath = getMainModulePath(
      resolve(appFullPath, entryModule),
      tsConfigName
    );
    if (appModuleRelativePath) {
      const appModuleFolderPath = dirname(
        resolve(appFullPath, appModuleRelativePath)
      );
      // include the lazy loader inside app module
      ngCompilerTransformers.push(nsReplaceLazyLoader);
      // include the new lazy loader path in the allowed ones
      additionalLazyModuleResources.push(appModuleFolderPath);
    }
  }

  const ngCompilerPlugin = new AngularCompilerPlugin({
    hostReplacementPaths: nsWebpack.getResolver([platform, 'tns']),
    platformTransformers: ngCompilerTransformers.map(t =>
      t(() => ngCompilerPlugin, resolve(appFullPath, entryModule), projectRoot)
    ),
    mainPath: join(appFullPath, entryModule),
    tsConfigPath: join(__dirname, tsConfigName),
    skipCodeGeneration: !aot,
    sourceMap: !!isAnySourceMapEnabled,
    additionalLazyModuleResources: additionalLazyModuleResources
  });

  let sourceMapFilename = nsWebpack.getSourceMapFilename(
    hiddenSourceMap,
    __dirname,
    dist
  );

  const itemsToClean = [`${dist}/**/*`];
  if (platform === 'android') {
    itemsToClean.push(
      `${join(
        projectRoot,
        'platforms',
        'android',
        'app',
        'src',
        'main',
        'assets',
        'snapshots'
      )}`
    );
    itemsToClean.push(
      `${join(
        projectRoot,
        'platforms',
        'android',
        'app',
        'build',
        'configurations',
        'nativescript-android-snapshot'
      )}`
    );
  }

  nsWebpack.processAppComponents(appComponents, platform);
  const config = {
    mode: production ? 'production' : 'development',
    context: appFullPath,
    externals,
    watchOptions: {
      ignored: [
        appResourcesFullPath,
        // Don't watch hidden files
        '**/.*'
      ]
    },
    target: nativescriptTarget,
    entry: entries,
    output: {
      pathinfo: false,
      path: dist,
      sourceMapFilename,
      libraryTarget: 'commonjs2',
      filename: '[name].js',
      globalObject: 'global',
      hashSalt
    },
    resolve: {
      extensions: ['.ts', '.js', '.scss', '.css'],
      modules: [
        resolve(__dirname, 'node_modules/@nativescript/core'),
        resolve(__dirname, 'node_modules'),
        'node_modules/@nativescript/core',
        'node_modules'
      ],
      alias: {
        '~': appFullPath,
        "tns-core-modules": "@nativescript/core",
        "nativescript-angular": "@nativescript/angular"
      },
      symlinks: true
    },
    resolveLoader: {
      symlinks: false
    },
    node: {
      // Disable node shims that conflict with NativeScript
      http: false,
      timers: false,
      setImmediate: false,
      fs: 'empty',
      __dirname: false
    },
    devtool: hiddenSourceMap
      ? 'hidden-source-map'
      : sourceMap
      ? 'inline-source-map'
      : 'none',
    optimization: {
      runtimeChunk: 'single',
      splitChunks: {
        cacheGroups: {
          vendor: {
            name: 'vendor',
            chunks: 'all',
            test: (module, chunks) => {
              const moduleName = module.nameForCondition
                ? module.nameForCondition()
                : '';
              return (
                /[\\/]node_modules[\\/]/.test(moduleName) ||
                appComponents.some(comp => comp === moduleName)
              );
            },
            enforce: true
          }
        }
      },
      minimize: !!uglify,
      minimizer: [
        new TerserPlugin({
          parallel: true,
          cache: !ci,
          sourceMap: isAnySourceMapEnabled,
          terserOptions: {
            output: {
              comments: false,
              semicolons: !isAnySourceMapEnabled
            },
            compress: {
              // The Android SBG has problems parsing the output
              // when these options are enabled
              collapse_vars: platform !== 'android',
              sequences: platform !== 'android'
            }
          }
        })
      ]
    },
    module: {
      rules: [
        {
          include: join(appFullPath, entryPath),
          use: [
            // Require all Android app components
            platform === 'android' && {
              loader: 'nativescript-dev-webpack/android-app-components-loader',
              options: { modules: appComponents }
            },

            {
              loader: 'nativescript-dev-webpack/bundle-config-loader',
              options: {
                angular: true,
                loadCss: !snapshot, // load the application css if in debug mode
                unitTesting,
                appFullPath,
                projectRoot,
                ignoredFiles: nsWebpack.getUserDefinedEntries(entries, platform)
              }
            }
          ].filter(loader => !!loader)
        },

        { test: /\.html$|\.xml$/, use: 'raw-loader' },

        // tns-core-modules reads the app.css and its imports using css-loader
        {
          test: /[\/|\\]app\.css$/,
          use: [
            'nativescript-dev-webpack/style-hot-loader',
            { loader: 'css-loader', options: { url: false } }
          ]
        },
        {
          test: /[\/|\\]app\.scss$/,
          use: [
            'nativescript-dev-webpack/style-hot-loader',
            { loader: 'css-loader', options: { url: false } },
            'sass-loader'
          ]
        },

        // Angular components reference css files and their imports using raw-loader
        { test: /\.css$/, exclude: /[\/|\\]app\.css$/, use: 'raw-loader' },
        {
          test: /\.scss$/,
          exclude: /[\/|\\]app\.scss$/,
          use: ['raw-loader', 'resolve-url-loader', 'sass-loader']
        },

        {
          test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
          use: [
            'nativescript-dev-webpack/moduleid-compat-loader',
            'nativescript-dev-webpack/lazy-ngmodule-hot-loader',
            '@ngtools/webpack'
          ]
        },

        // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
        // Removing this will cause deprecation warnings to appear.
        {
          test: /[\/\\]@angular[\/\\]core[\/\\].+\.js$/,
          parser: { system: true }
        }
      ]
    },
    plugins: [
      // Define useful constants like TNS_WEBPACK
      new webpack.DefinePlugin({
        'global.TNS_WEBPACK': 'true',
        process: 'global.process'
      }),
      // Remove all files from the out dir.
      new CleanWebpackPlugin(itemsToClean, { verbose: !!verbose }),
      // Copy assets to out dir. Add your own globs as needed.
      new CopyWebpackPlugin(copyTargets, {
        ignore: [`${relative(appPath, appResourcesFullPath)}/**`]
      }),
      new nsWebpack.GenerateNativeScriptEntryPointsPlugin('bundle'),
      // For instructions on how to set up workers with webpack
      // check out https://github.com/nativescript/worker-loader
      new NativeScriptWorkerPlugin(),
      ngCompilerPlugin,
      // Does IPC communication with the {N} CLI to notify events when running in watch mode.
      new nsWebpack.WatchStateLoggerPlugin()
    ]
  };

  if (report) {
    // Generate report files for bundles content
    config.plugins.push(
      new BundleAnalyzerPlugin({
        analyzerMode: 'static',
        openAnalyzer: false,
        generateStatsFile: true,
        reportFilename: resolve(projectRoot, 'report', `report.html`),
        statsFilename: resolve(projectRoot, 'report', `stats.json`)
      })
    );
  }

  if (!production && hmr) {
    config.plugins.push(new webpack.HotModuleReplacementPlugin());
  }

  return config;
};

@hrueger
Copy link

hrueger commented Jun 4, 2020

@NathanWalker Thanks, unfortunately I still have issue #2171 so I can't confirm that it's working.

@NathanWalker
Copy link
Contributor

@hrueger that issue is covered in the wiki here - just got you details in that issue 👍

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