Closed chriswep closed 7 years ago
Just tried installing typescript@next
and it still errors on async when targeting ES5. How did you get it to work?
Nevermind, I'm a moron.
@metz FWIW I can successfully use async/await while targeting ES5 with ionic dev
builds (using the hack below), but I haven't figured out a fix for prod
builds yet.
This new ionic-app-scripts
build system does two kinds of builds, dev
and prod
. Both systems use a project's tsconfig.json
file, but the version of typescript that actually gets used for the build is inconsistent between them. (I should probably create a new issue for that...)
prod
does AOT builds that ultimately invoke angular 2's tsc-wrapped
module, and the angular 2 AOT compiler will respect a project's locally-installed typescript version. When I try doing a prod
build via npm run build
with a locally-installed typescript@2.1.0-dev.20161019
, for example, I get this error:
Error: Metadata emit requires the sourceFiles are passed to WriteFileCallback. Update to
TypeScript ^1.9.0-dev
ngc failed
ionic-app-script task: "build"
Error: Error
That Metadata emit requires...
error is thrown in the @angular/tsc-wrapped/src/compiler_host.js
file. It's not clear to me if it's strictly an angular 2 issue, or if the sourceFiles
arg in their writeFile
overload is empty because the ionic build system isn't providing what it needs correctly when using TS 2.1.0-dev.*.
Unlike prod
builds, dev
builds use a pinned typescript that's currently at 2.0.3, because the app-scripts module has typescript listed as a dependency
instead of a peerDependency
. That means, when doing dev
builds, app-scripts ignores whatever version of typescript you have installed in your project and uses the one in @ionic/app-scripts/node_modules/typescript
instead. That one happens to be 2.0.3
in my install, because their package.json
declares the dependency as ^2.0.3
(which wouldn't pick up the 2.1.0-dev builds anyway even if it was listed like that as a peerDependency
instead - I think it would need to be ^2.0.3 || ^2.1.0-dev
). It's confusing, because the app-scripts build does respect the tsconfig.json
file in your project. This seems like a bug!
As a workaround to at least enable async/await in non-AOT dev builds while they sort this stuff out, I was able to force app-scripts
to respect the newer typescript 2.1.0-dev version installed in my project's node_modules
folder by opening a terminal in @ionic/app-scripts
and running npm uninstall --save typescript
to get rid of the 2.0.3 version in their nested node_modules
folder. Then, since node won't find it locally, it bubbles up to the node_modules
folder in my project and use that one instead.
I also changed the build
script in package.json
to:
"build": "ionic-app-scripts build --dev"
to force dev builds even when using ionic run android
and such that would otherwise use prod
builds.
So assuming angular support for typescript 2.1.0 arrives sometime soon for AOT builds, this enables coding using the convenience of async/await in the meantime. On-device debugging is much faster with non-AOT builds anyway, so this is what I was doing already.
thanks @rob3c for the detailed explanations, that cleared things up a bit.
@metzc, @rob3c,
For now, don't do this 😆 . We want to support this, but we can't yet. We are limited by Angular AoT. There are also known issues with Typescript transpiling ES2017 to ES5 and uglify-js, etc.
We will add this support as soon as we can but for now it's not something we can offer support for now. Hopefully soon, as I am a huge async/await fanboy.
Thanks, Dan
I'd suggest the team not close this issue... Perhaps tag it as angular-dependent or something, but this is still an active issue that is helpful for users to know about. It shouldn't be closed.
With the team's transition to Webpack, I've had great success with hooking babel-loader into the Webpack config after their custom loader, and then telling TS to generate ES2015. It works perfectly. Its not ideal, but I'll take it.
@bytenik : Could you upload your configuration files? This would be very helpful! I tried something similar but did not succeed :(
All,
I don't recommend going off and starting to customize the webpack config yet. Consider that "ejecting" like create-react-app. We can't support custom configs, especially when we're very early in the process with Webpack and app-scripts in general.
Thanks, Dan
The following is what I used:
let config = require('@ionic/app-scripts/config/webpack.config.js');
const path = require('path');
console.log("Using alternate Webpack script");
config.devtool = 'source-map';
let loaderEntry = config.module.loaders[0];
let presetPath = path.join(__dirname, '../node_modules/babel-preset-es2015').split('\\').join('/');
loaderEntry.loaders = [ loaderEntry.loader, `babel-loader?{"cacheDirectory": true, "babelrc": false, "presets": [ ["${presetPath}", { "modules": false }] ]}` ];
delete loaderEntry.loader;
module.exports = config;
@danbucholtz I know its not recommended, but I don't really have a choice. Without AOT compilation, Ionic2 is unbearably slow on devices for my app -- too slow to deploy. And I already have a mostly built app from the Ionic2 betas, which uses async/await because I had added Babel into the gulp build. At this point, I don't really have an option but to tweak the current rc1 build process.
@bytenik,
Sounds good. I understand people are going to need to customize. I totally, 110% get it. My fear is that since we're iterating very quickly right now there will be breaking changes, etc. We'll provide some hooks to make it easy to inject data, etc. For transpiling, adding a loader to Webpack is probably going to be the fastest way to do it.
Thanks, Dan
@danbucholtz Once again, can we please leave this issue open? As it is, in fact, an open issue. Clearly there's a need / want for this functionality, and it is a bug when dealing with Ionic v2. This shouldn't be closed.
@danbucholtz Do you have any specific angular, typescript and/or uglifyjs issues you can link to that are holding this up so that we can track them? Are there any other blocking problems with dependencies that don't have corresponding issues yet and still need to be created?
@bytenik Do you have a sample repo for this babel transpiling usage? I can't get it to work with the script that you posted.
It works out of the box on 0.0.37. The newer app scripts versions appear to have changed everything.
@Kobzol it also didn't work for me. here is my relevant part of the webpack.config:
config.module.loaders.push(
{
test: /\.js$/,
loader: 'babel',
exclude: path.resolve(__dirname, 'node_modules/'),
query: {
presets: [
['es2015', {
"modules": false
}],
'stage-0'
]
}
}
);
Please note that for async/await to work i also have to import the babel-generator-runtime within my app code.
We are working on bundling our dependencies for app-scripts to speed up install time. Once that's done, I'll address this. I think we can get away with a peerDependency
of *
for TypeScript
and @angular/compiler-cli
. This should take care of the issues and you can use the async/await with ES5 target.
Thanks, Dan
@metzc Thank you, with that config I finally managed it to work x)
@Kobzol @metzc could you kindly elaborate on how you got Ionic to work with TS 2.1?
@jamespacileo I didn't use Typescript 2.1, I just used the webpack config script provided by @metzc to transcript ES6 to ES5 with Babel. I created a script with the config that @metzc posted and added this to my package.json
:
"config": { "ionic_webpack": "<path_to_the_script>" }
Make sure that the exclude path in the config file does point to your node_modules
folder or it won't probably work and it will give strange errors since it will try to transpile your libraries. For the example script given by @metzc, the config file should be stored in the project root, where package.json
is.
Then I installed
"babel-core": "^6.18.0",
"babel-loader": "^6.2.7",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-external-helpers": "^6.8.0",
"babel-plugin-external-helpers-2": "^6.3.13",
"babel-plugin-native-async-for-typescript": "^1.0.3",
"babel-plugin-syntax-async-generators": "^6.13.0",
"babel-plugin-transform-async-to-generator": "^6.16.0",
"babel-plugin-transform-regenerator": "^6.16.1",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-polyfill": "^6.16.0",
"babel-preset-es2015": "^6.18.0",
"babel-preset-es2015-loose": "^8.0.0",
"babel-preset-es2015-rollup": "^1.2.0",
"babel-preset-stage-0": "^6.16.0",
I'm pretty sure that not even half of those packages are required, but it was a trial-and-error until it worked, so I'm posting all of them.
Then I had to add the regenerator runtime to my code, but Ionic doesn't support multiple webpack entries at this moment and I had no luck with importing it in code, so I simply copied the runtime.js
file from node_modules/regenerator-runtime
to the src dir and included it in the head of index.html
.
The only other thing necessary was to either turn off uglifyjs or use a newer version that handles ES6 (as stated in #239). After that async/await
started to work on my mobile device :-)
to give some context: typescript 2.1 right now is not working with Angular 2 AOT, thats why we can't use it (for production builds). If it would work, we could just use async/await out of the box because 2.1 can transpile it to ES5.
The workaround is to set the target of typescript to ES6 and transpile this to ES5 with webpack (which is able to transpile async/await for ES5).
On a side note: I was able to just do
import 'babel-regenerator-runtime';
in my app code.
@Kobzol @metzc thanks a ton! Worked like a charm! I appreciate the time and hard work it took to find a workaround and sharing the steps in such details. I'm so happy I can finally use async/await! Thanks 👍
If you're using app-scripts version 0.0.46
or newer, change the loader: 'babel'
line to loader: 'babel-loader'
.
Any news on when this will run flawlessly? I only changed a thing on tsconfig.json, "target":"es5" to "target":"es2015" and async/await works on my android phone but not on emulator.
@iursevla with only your change you end up with ES6 code in your build. though this works on some browsers and devices (say: iOS10 partly, newest chrome browser) you can't rely on it just now. maybe in 2 years or something but right now you definitely need to transpile to ES5 for production.
@metzc thanks for your reply. What's the solution with the least changes i can do to make async/await work across all devices and emulators?
Just as an FYI, Typescript 2.1 doesn't work with our build process yet but we landed a PR to make it so. They changed an existing public API. We have made the changes necessary with peerDependencies already.
Thanks, Dan
A pull request to their code, or to Ionic?
It looks like it was merged several days ago. Does that mean that typescript@next
works with the latest app-scripts?
@bytenik,
Not the latest published, no, but the latest nightly
(which is probably buggy) may work. I'm not sure. I haven't tested it, but the changes to the package.json involving peerDependencies are in place. I am a huge async/await fan so we'll make sure this works well soon. But there are bigger fish to fry first and we're a small team.
Thanks, Dan
FWIW, I gave it a try anyway. No patience here. 😀 There still seems to be an issue between the @angular/compiler(-cli?) and TypeScript:
TypeError: Cannot read property 'text' of undefined
at NodeObject.getText (C:\Users\bytenik\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:78064:30)
at Evaluator.evaluateNode (C:\Users\bytenik\AppData\Roaming\npm\node_modules\@angular\compiler-cli\node_modules\@angular\tsc-wrapped\src\evaluator.js:495:66)
at _loop_1 (C:\Users\bytenik\AppData\Roaming\npm\node_modules\@angular\compiler-cli\node_modules\@angular\tsc-wrapped\src\collector.js:306:54)
at C:\Users\bytenik\AppData\Roaming\npm\node_modules\@angular\compiler-cli\node_modules\@angular\tsc-wrapped\src\collector.js:365:25
at visitEachNode (C:\Users\bytenik\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:13907:30)
at Object.forEachChild (C:\Users\bytenik\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:14078:24)
at MetadataCollector.getMetadata (C:\Users\bytenik\AppData\Roaming\npm\node_modules\@angular\compiler-cli\node_modules\@angular\tsc-wrapped\src\collector.js:204:12)
at MetadataWriterHost.writeMetadata (C:\Users\bytenik\AppData\Roaming\npm\node_modules\@angular\compiler-cli\node_modules\@angular\tsc-wrapped\src\compiler_host.js:111:51)
at MetadataWriterHost.writeFile (C:\Users\bytenik\AppData\Roaming\npm\node_modules\@angular\compiler-cli\node_modules\@angular\tsc-wrapped\src\compiler_host.js:103:19)
at Object.writeFile (C:\Users\bytenik\AppData\Roaming\npm\node_modules\typescript\lib\typescript.js:62519:132)
Compilation failed
If there's still an issue between compiler-cli and Typescript 2.1, could someone (who knows what the problem is) kindly raise an issue on the Angular github? 😄
They've closed a few issues already stating that AOT is compatible with 1.8+ (2.1 included) and that there is no issue.
I'm not exactly sure how to reproduce this enough to submit a ticket. I know it fails on my codebase, but I don't know that it will fail on another. @jamespacileo are you able to try this out with your code and see if it fails?
@bytenik ok, I'll give it a shot this evening. Hopefully I reproduce the same error, or even better... get a successful compilation. :)
@jamespacileo Any luck?
for me there is still the same problem / output that i posted initially on this issue. i tried with the official typescript 2.1 release as well as nightly. i then even updated ionic-angular as well as app-scripts to nightly (and angular accordingly). no success.
is there any working example with typescript >= 2.1 and angular when using the ngc compiler (and at best ionic2)? Then i could work from there. However it seems to me that this is independent from my setup.
@metzc,
I haven't tried it yet. We are holding off on updating to TS 2.1 until after 2.0.0 final.
Thanks, Dan
I can't tell you how disappointed I am that Ionic2 will be released on an already-obsolete TypeScript version. 😭
@danbucholtz i wouldn't complain, since you are doing a great job here. apart from that i am very much looking forward to a coming Ionic2 support of TS 2.1, seeing that it is released now. I am using its new features regularly in other projects and find them to greatly improve the platform as a development environment.
@bytenik, Not our fault. Angular doesn't support Typescript 2.1. There are many open issues about it. We tried to upgrade a few weeks back, and tried again today. No dice in Angular 2.3. I don't have the issue handy but if you search TypeScript 2.1 in Angular repo you'll see a slew of issues.
Thanks, Dan
TypeScript 2.1 (2.2?) support will come to Angular when they bump to 4.0.
Details in Igor's recent talk here.
Angular 4 is scheduled for march. Hopefully that means we'll get a beta/alpha/RC way before then.
TS 2.1 is very important to me, so I'll be keeping a close eye on the Angular github. On Wed, 14 Dec 2016 at 23:14, Patrick McDonald notifications@github.com wrote:
TypeScript 2.1 (2.2?) support will come to Angular when they bump to 4.0.
Details in Igor's recent talk here https://youtu.be/aJIMoLgqU_o?t=843.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/driftyco/ionic-app-scripts/issues/197#issuecomment-267186925, or mute the thread https://github.com/notifications/unsubscribe-auth/AAlKZO95E-QAM2GlXJ4Zsgb9a_6uwBVMks5rIHhXgaJpZM4KbAcH .
@jamespacileo, I'm personally as anxious for it as you are. We'll get it in there as soon as we can. Everything on our end is ready to go.
Thanks, Dan
I don't know what I am doing wrong, but for me Typescript 2.1 works just fine with Ionic.
@Flavien including building and deploying to a device?
I've found that using typescript 2.1 and running ionic serve
is fine, but the problems only come about when running ionic run android
- that's when the ng compiler kicks in, and starts causing problems.
I even created a brand new blank Ionic app, only upgraded typescript to 2.1, and that failed to run on the device.
Ok, I've only try with dev builds (Ripple emulator and Android emulator), haven't tried on an actual device.
@danbucholtz as you guys probably now angular 4 is published as beta on npm now. just gave it a shot if it would work but i didn't come far due to changes in angular that ionic-app-scripts is not compatible with. Just for your reference: angular moved ReflectorHost from compiler-cli to language-services. Thats at least one thing that would need to be fixed.
Wonder if you would try to switch to the angular 4 betas before March 2017? In nightly / separate branch? I would appreciate.
@metzc,
We will certainly be integrating Angular 4 earlier than that. It'll probably be in a separate branch and published as beta
or something.
Thanks, Dan
I like to use typescript 2.1 (which is right now in the @next channel) because it enables me to use async/await while still targeting ES5.
Anyway, when using ionic build, i.e. the ngc AOT compiler, the build breaks with
Downgrading to typescript 2.0.3 solves the problem.