Skip to content
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

1.6 beta support? #73

Closed
johnnyreilly opened this issue Sep 12, 2015 · 21 comments
Closed

1.6 beta support? #73

johnnyreilly opened this issue Sep 12, 2015 · 21 comments

Comments

@johnnyreilly
Copy link
Member

Heya,

In my downtime I've been working on trying to port an existing project written using React, Babel + Browserify across to my beloved TypeScript. Last time I attempted this I failed badly, probably due to the lack of JSX support in TypeScript. However, with TS 1.6 getting all ES6-y and JSX-y I thought I'd reattempt, prompted by @mhegazy in this thread: microsoft/TypeScript#4337 (comment)

Anyway, I've had first crack at this and whilst atom-typescript seems pretty happy with the code, TSIFY is most assuredly not. It dies a death like this:

:\Source\globalize-so-what-cha-want-typescript [master +13 ~3 -11 !]> npm run build

> globalize-so-what-cha-want@0.8.2 build C:\Source\globalize-so-what-cha-want-typescript
> gulp build

[06:04:06] Using gulpfile C:\Source\globalize-so-what-cha-want-typescript\gulpFile.js
[06:04:06] Starting 'build'...
[06:04:06] Finished 'build' after 172 ms
[06:04:07] gulp-notify: [APP Bundle] Failing to build...
[06:04:07] { [TypeScript error: src/demo/main.ts(2,24): Error TS2307: Cannot find module 'react'.]
  message: 'src/demo/main.ts(2,24): Error TS2307: Cannot find module \'react\'.',
  fileName: 'src/demo/main.ts',
  line: 2,
  column: 24,
  name: 'TypeScript error' }
[06:04:07] There is a problem in the app bundle!
[06:04:07] gulp-notify: [APP Bundle] Failing to build...
[06:04:07] { [TypeScript error: src/demo/main.ts(3,17): Error TS2307: Cannot find module './components/App'.]
  message: 'src/demo/main.ts(3,17): Error TS2307: Cannot find module \'./components/App\'.',
  fileName: 'src/demo/main.ts',
  line: 3,
  column: 17,
  name: 'TypeScript error' }
[06:04:07] There is a problem in the app bundle!
[06:04:08] gulp-notify: [APP Bundle] Failing to build...
[06:04:08]
C:\Source\globalize-so-what-cha-want-typescript\src\demo\main.ts:1
import * as React from 'react';
^
ParseError: 'import' and 'export' may appear only with 'sourceType: module'

Does TSIFY support TypeScript 1.6 beta? I'm trying to understand what's causing these problems. For now I've dropped Babel out of the mix entirely, I'm just trying to compile. And failing.

I'm not sure if this is a problem of my own stupidity (entirely possible) or that the tooling is not quite there yet. Any insights would be greatly appreciated. You can see the port here:

https://github.com/johnnyreilly/globalize-so-what-cha-want-typescript

And for reference the original code is here:

https://github.com/johnnyreilly/globalize-so-what-cha-want

@mhegazy if you were able to provide any insight that would be fantastic. I know from @jbrantly's work that a webpack / typescript / babel workflow is possible. Given that I'm happily using Browserify (which fulfils a similar purpose to WebPack) I assumed the same was possible and set out to try prove it. Unfortunately, I'm not there yet and I'm out of ideas.

@smrq
Copy link
Member

smrq commented Sep 12, 2015

Error TS2307: Cannot find module 'react'.

It's not finding the typings file for React, are you including it? The files config in tsconfig.json is ignored since Browserify needs to know the entry point(s) to your app, so you either have to /// it or add your *.d.ts file(s) in your Browserify config.

Error TS2307: Cannot find module './components/App'.

This is a *.tsx file, which Browserify will not look for by default. tsify adds *.ts to the list of extensions, but I didn't add *.tsx as well because every extra extension causes some level of performance degradation at module resolution time, so you have to do this one manually in the Browserify options. (Although, *.tsx could probably be added if the jsx compiler option is set. I'll make an issue for that.)

ParseError: 'import' and 'export' may appear only with 'sourceType: module'

Since you're targeting ES6 you have to go through Babelify as well (Browserify doesn't support ES6 modules afaik). I'll be honest, I haven't tried using both tsify and Babelify, so I have no idea if there are pipelining issues or anything like that. Hopefully it should Just Work™.

@johnnyreilly
Copy link
Member Author

Thanks for the response @smrq - I really appreciate it.

Error TS2307: Cannot find module 'react'.

It's not finding the typings file for React, are you including it? The files config in tsconfig.json is ignored since Browserify needs to know the entry point(s) to your app, so you either have to /// it or add your *.d.ts file(s) in your Browserify config.

I wasn't but I am now. It looks like this:

  var appBundler = browserify({
    entries: ['./src/demo/main.ts', './typings/react/react.d.ts', './typings/flux/flux.d.ts', './typings/node/node.d.ts'], // being explicit as globs don't appear to work; trying this failed: ['./src/demo/main.ts', './typings/**/*.*.ts']
// Babelify excluded until I can get TSIFY to compile
//    transform: [babelify.configure({ sourceMaps: false, stage: 3 })], 
    debug: options.isDevelopment,
    cache: {}, packageCache: {}, fullPaths: options.isDevelopment
  })
  .external(dependencies)
  .plugin('tsify');

I'm now down to just this error:

[22:19:53] { [TypeScript error: src/demo/main.ts(3,17): Error TS2307: Cannot find module './components/App'.]
  message: 'src/demo/main.ts(3,17): Error TS2307: Cannot find module \'./components/App\'.',
  fileName: 'src/demo/main.ts',
  line: 3,
  column: 17,
  name: 'TypeScript error' }

And that sounds like it would be resolved by #76. Thanks for picking up on that.

ParseError: 'import' and 'export' may appear only with 'sourceType: module'

Since you're targeting ES6 you have to go through Babelify as well (Browserify doesn't support ES6 modules afaik). I'll be honest, I haven't tried using both tsify and Babelify, so I have no idea if there are pipelining issues or anything like that. Hopefully it should Just Work™.

Yup - I'm planning to use Babelify to do the transpilation and just use TypeScript for static typing. I'm puzzled to get the ParseError: 'import' and 'export' may... when just compiling with TSIFY though. Perhaps I'm missing something.

I'm still getting this:

> [22:44:34] gulp-notify: [APP Bundle] Failing to build...
> [22:44:34]
> C:\Source\globalize-so-what-cha-want-typescript\src\demo\main.ts:1
> import * as React from 'react';
> ^
> ParseError: 'import' and 'export' may appear only with 'sourceType: module'

I think it may be related to the typings I'm using being not ES6 definition files as discussed by @jbrantly in his post here. I might play with them a little and see if it resolves things.

Question: Babelify is a transform and TSIFY is a plugin. My thinking is that TSIFY needs to run before Babelify does to give us the output we want. Do you know if this is the case? That TSIFY is running before Babelify.

Thanks again for your assistance. I've updated my repo with the tweaks I've discussed here.

@smrq
Copy link
Member

smrq commented Sep 15, 2015

Babelify is a transform and TSIFY is a plugin. My thinking is that TSIFY needs to run before Babelify does to give us the output we want. Do you know if this is the case? That TSIFY is running before Babelify.

Yep, definitely the case. In fact, it's impossible for anything to run before tsify, which is potentially a drawback (if you had any preprocessing on the actual TS source you want to run, well, it can't presently be done) but in this case it works out exactly as desired.

@johnnyreilly
Copy link
Member Author

Excellent! Thanks

@smrq
Copy link
Member

smrq commented Sep 15, 2015

Update for #76 is released in 0.11.15 so you should be good now.

@johnnyreilly
Copy link
Member Author

Thanks - I'll give it a try and report back...

@johnnyreilly
Copy link
Member Author

Hi @smrq,

It's trying to process those files now but dying a death. You receive an error like this:

C:\Source\globalize-so-what-cha-want-typescript [master +1 ~3 -0 !]> npm run build-demo

> globalize-so-what-cha-want@0.9.0 build-demo C:\Source\globalize-so-what-cha-want-typescript
> gulp build

[05:54:54] Using gulpfile C:\Source\globalize-so-what-cha-want-typescript\gulpFile.js
[05:54:54] Starting 'build'...
[05:54:54] Finished 'build' after 166 ms
[05:54:56] gulp-notify: [APP Bundle] Failing to build...
[05:54:56] { [TypeScript error: src/demo/components/App.tsx(43,36): Error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.]
  message: 'src/demo/components/App.tsx(43,36): Error TS2339: Property \'assign\' does not exist on type \'ObjectConstructor\'.',
  fileName: 'src/demo/components/App.tsx',
  line: 43,
  column: 36,
  name: 'TypeScript error' }
[05:54:56] There is a problem in the app bundle!
[05:54:56] gulp-notify: [APP Bundle] Failing to build...
[05:54:56] { [TypeScript error: src/demo/components/App.tsx(44,85): Error TS17004: Cannot use JSX unless the '--jsx' flag is provided.]
  message: 'src/demo/components/App.tsx(44,85): Error TS17004: Cannot use JSX unless the \'--jsx\' flag is provided.',
  fileName: 'src/demo/components/App.tsx',
  line: 44,
  column: 85,
  name: 'TypeScript error' }

Every TSX file appears to generating the following error as well:

[05:34:42] { [TypeScript error: src/demo/components/ModuleSelector.tsx(16,66): Error TS17004: Cannot use JSX unless the '--jsx' flag is provided.]
message: 'src/demo/components/ModuleSelector.tsx(16,66): Error TS17004: Cannot use JSX unless the '--jsx' flag is provided.',
fileName: 'src/demo/components/ModuleSelector.tsx',
line: 16,
column: 66,
name: 'TypeScript error' }

Perhaps the jsx flag from my tsconfig.json is not being passed on to the compiler?

    "compilerOptions": {
        "jsx": "preserve",
        "target": "es6",
        "noImplicitAny": false,
        "removeComments": false,
        "preserveConstEnums": true,
        "sourceMap": true
    },

I have no idea what's causing the Error TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.] But the same code compiles happily with atom-typescript...

@johnnyreilly
Copy link
Member Author

You can see the state of the failing build here: https://ci.appveyor.com/project/JohnReilly/globalize-so-what-cha-want-typescript

@madmikeross
Copy link

I believe I have this sorted. @johnnyreilly make sure you set your jsx option to 'react'.

.plugin('tsify', {
  jsx: 'react',
  typescript: require('typescript')
});

Otherwise, when it's set to 'preserve', it balks at the unexpected token (the jsx html markup) like so:

[17:02:43] Starting 'tsify'...
events.js:85
      throw er; // Unhandled 'error' event
            ^
Error: Parsing file C:\Users\Michael\Development\Nimbus\Dev\Nimbus.Web\Nimbus.Client\src\app\company\CreateCompany.tsx: Unexpected token (65:19)
    at Deps.parseDeps (C:\Users\Michael\Development\Nimbus\Dev\node_modules\browserify\node_modules\module-deps\index.js:437:28)
    ...

Given @smrq 's most recent change from 2 days ago, the jsx option automatically adds .tsx file extension resolution to browserify.

Now I just need to work some magic so I can require in css at the top of my .tsx files (was using strictly webpack before, but it wouldn't feed karma a bundle with 'fs' included, but I digress)

@johnnyreilly
Copy link
Member Author

Hi @semblant,

I currently have my jsx field set in the tsconfig.json like so:

{
    "compileOnSave": false,
    "filesGlob": [
        "../../typings/**/*.*.ts",
        "**/*.ts",
        "**/*.tsx"
    ],
    "version": "1.6.0-beta",
    "compilerOptions": {
        "jsx": "preserve",
        "target": "es6",
        "noImplicitAny": false,
        "removeComments": false,
        "preserveConstEnums": true,
        "sourceMap": true
    },
    "files": [
        "../../typings/flux/flux.d.ts",
        "../../typings/node/node.d.ts",
        "../../typings/react/react.d.ts",
        "actions/ModuleActions.ts",
        "constants/action-types/ModuleActionTypes.ts",
        "dependencies.ts",
        "dispatcher/AppDispatcher.ts",
        "main.ts",
        "stores/FluxStore.ts",
        "stores/ModuleStore.ts",
        "components/App.tsx",
        "components/Module.tsx",
        "components/ModuleSelector.tsx"
    ]
}

I'm using preserve as I want Babel to do the JSX transformation. Does tsify not read the tsconfig.json? I was pretty sure it did...

I can't help but notice that the way you're plugging in TSIFY to Browserify differs to mine:

.plugin('tsify', {
  jsx: 'react',
  typescript: require('typescript')
});

Whereas I'm just:

  .plugin('tsify');

Am I doing it wrong? The docs aren't clear...

@madmikeross
Copy link

@johnnyreilly thanks for the idiot check on the tsify plugin. I ripped out my odd configuration and it is indeed reading from tsconfig.json.

In my first comment I overlooked the fact that you are using Babel and targeting ES6. I will fiddle with adding Babel to the mix and report back with any success/failure.

@johnnyreilly
Copy link
Member Author

Thanks chap!

@madmikeross
Copy link

Having orbited this issue, and related issues, for a few weeks now, I'm inclined to agree with @johnnyreilly 's earlier statement that the tooling might not quite be there yet (at least when used in concert). I have read through the other related issues and comments you posted John, and I think you were closest when you were considering using gulp-typescript in July.

In the project I'm currently on, I was targeting ES5. As of yesterday, I moved to browserify bundling to avoid a webpack->karma issue. As of this morning, I converted the imports and exports appropriately to investigate the ES6 target option. I have bumped into the exact error you encountered, namely

'import' and 'export' may appear only with 'sourceType: module'

Now you could set about the Sisyphean task of restructuring your dependencies, but I think this is going to be a recurring problem for most external dependencies as many authors do not structure their module exports according to the ES6 convention.

Perhaps the best workaround would be to target ES6 and use gulp-typescript to dump into a js src folder. Then babel/browserify the js in that folder. I realize this kills the convenience of the gulp stream and probably increases time to rebundle significantly, but I have not found another viable option.

To be honest, while TypeScript doesn't support as many ES6 features as Babel, I think it might be easiest just to target ES5 in your tsconfig, set the jsx flag to 'react', and use tsify straight away, dropping Babel.

I'm equally frustrated that there isn't an elegant way to accomplish the desired workflow.

@johnnyreilly
Copy link
Member Author

Thanks for the reflections @semblant. On the one hand I'm tempted to go with your suggestion of just going with TSIFY but I want to write es6 code and TypeScript only down compiles some constructs. There's a way to use core js with TS but there's a dearth of guidance alas:

microsoft/TypeScript#3956

There's also switching to using WebPack as there's @jbrantly's solution already in place: http://www.jbrantly.com/es6-modules-with-typescript-and-webpack/

I don't want to ditch Browserify unless I have to though - and I feel we must be close.... I'm hoping @smrq has some insights - we can do it.... Somehow!

@madmikeross
Copy link

@johnnyreilly I had had a lot of success with @jbrantly 's set up. He maintains his ts-loader well. The only caution I offer, I ran into trouble when bundling tests for karma. Vanilla unit tests in something like mocha work fine, but if you have a bdd test framework that needs node's 'fs' module you might run into the same trouble I've had.

I will keep up, hopefully we can find a solution.

@angularsen
Copy link

@semblant I tried webpack + tsloader, but am having issues when targeting ES6 in TypeScript and generating source map files. It all works very well when targeting ES5, though, or when not generating source map files.

Could you possibly post your setup?

@madmikeross
Copy link

@anjdreas I moved back to ES5 for the time being. I don't recall having issues with sourcemaps in ES6 though. I have pasted my setup below, the only things that have changed are my target in tsconfig, and my import syntax for certain 3rd party modules.

webpack.config.js

/* global process */
/* global __dirname */
var webpack = require('webpack');
var bower_dir = __dirname + '/bower_components';

var config = {
    devtool: 'source-map',
    addVendor: function(name, path) {
        this.resolve.alias[name] = path;
        this.module.noParse.push(new RegExp(path));
    },
    entry: {
        app: ["webpack/hot/dev-server", "./src/app/app.tsx"],
        vendors: ['react']
    },
    output: {
        path: process.env.NODE_ENV === 'production' ? '../js' : './build',
        filename: "bundle.js",
        sourceMapFilename: 'bundle.map.js'
    },
    resolve: {
        alias: {},
        extensions: ["", ".tsx", ".ts", ".js"]
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin('vendors', 'vendors.js')
    ],
    module: {
        noParse: [],
        loaders: [
            { test: /\.ts(x?)$/, loader: "ts-loader" },
            { test: /\.css$/, loader: "style-loader!css-loader" },
            {
                test: /\.woff($|\?)|\.woff2($|\?)|\.ttf($|\?)|\.eot($|\?)|\.svg($|\?)/,
                loader: "url-loader"
            },
            { test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
        ]
    }
}

// config.addVendor('react', bower_dir + '/react/react.min.js');
config.addVendor('react/addons', bower_dir + '/react/react-with-addons.js');
config.addVendor('bootstrap.css', bower_dir + '/bootstrap/dist/css/bootstrap.min.css')

module.exports = config;

tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "module": "commonjs",
        "jsx": "react",
        "sourceMap": true,
        "noImplicitAny": false
    },
    "files": [
        "./typings/tsd.d.ts",
        "./src/app/app.tsx"
    ]
}

The relevant bits might be the devtool option from the webpack config and the sourceMap option in tsconfig. You should also drop the module option in tsconfig when you target ES6. Hope that helps!

@angularsen
Copy link

Thanks, it's pretty much the same as my setup with ES5. Suppose I'll just wait a bit on ES6.

@cherrydev
Copy link

I feel like that this issue describes the problem that I'm having:

SyntaxError: 'import' and 'export' may appear only with 'sourceType: module'

But the title of the issue is inaccurate since tsify DOES support typescript 1.6, but it does not support using ES6 as the target. I've spent a while trying to figure out what might have been causing this, since I had also added babelify into the pipeline (which I've seen an example of) and thought it may have been babel, but after removing it I still had the problem. It took some digging until this conversation popped up.
Perhaps either the title should be changed or a new issue should be opened that specifically describes that problem? I'll open a new issue, but someone feel free to close it and change the title of this one instead if that's decided upon.

@johnnyreilly
Copy link
Member Author

I've just managed to get this up and running, but unit testing appears to be a no-go. Take a look at #90 for details.

@smrq
Copy link
Member

smrq commented Apr 20, 2016

Closing old issues; I think most(?) of these issues should be resolved with the recent updates to tsconfig handling.

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

No branches or pull requests

5 participants