jspm / jspm-cli

ES Module Package Manager
https://jspm.org
Apache License 2.0
3.78k stars 272 forks source link

Any working example of using jspm with Babel for React JSX files? #566

Closed hipertracker closed 9 years ago

hipertracker commented 9 years ago

I created a new jspm project with Babel. I don't know how to force it to understand JSX or how to pass more BabelJS parameters to transpiler. In my config.js file I have default "transpiler": "babel",. When I tried change it into transpiler: {name:"babel", options: {experiment:true}} I got error that I need Traceur (it looks like Babel is not detected anymore after that change). Do I also need to download babel.js and babel-polyfill.js in my index.html? Or it is already somehow supported by my config.js?

// config.js:
System.config({
  "baseURL": "/",
  "transpiler": "babel",
  "paths": {
    "*": "*.js",
    "github:*": "jspm_packages/github/*.js",
    "npm:*": "jspm_packages/npm/*.js"
  }
});
// ...
djindjic commented 9 years ago

https://github.com/tinkertrain/jspm-react

tritonrc commented 9 years ago

Per https://github.com/floatdrop/plugin-jsx jspm install jsx (or append @beta for ES6 friendly React 0.13)

hipertracker commented 9 years ago

I don't want to use Gulp top transpile ES6. I do not need jspm if I can use Gulp/Grunt/Broccoli. I need a pure browser solution. jspm should use babel out of box. Why to install another software or plugins?

egauci commented 9 years ago

I'm trying to figure this out too. Babel is supposed to support JSX, but even if I set the dl-loader to Babel, it still requires the floatdrop/plugin-jsx to work.

It's not horrid - it works fine without a separate build step. Still, in the Chrome debugger, the JSX is already transpiled in to JavaScript.

hipertracker commented 9 years ago

I need to see a full working example. Even with that plugin (I use it's fork) it's not clear how to use it. My index.html contains JS command System.import('lib/main'); and I get SyntaxError (in Chrome Developer Tool) on very first line of my file lib/main.js:

Potentially unhandled rejection [3] SyntaxError: Error loading "lib/main" at http://localhost:3000/lib/main.js
Evaluating lib/main
    Unexpected token <

That line is a simple ES6 import of React library

import React from 'react';

According to that JSX plugin I should use System.import('lib/main.jsx!') instead, but this won't work either because then I get another error. The browser try to download incorrect file: lib/main.jsx!jsx... It looke like that plugin is not compatible with jspm default config.js file which use *.js format for all files. It's all confused and unclear.

egauci commented 9 years ago

This is working for me: https://github.com/egauci/react-jspm-tests

hipertracker commented 9 years ago

No, this is not a jspm project. It was not created with jspm init command. That is jspm project: https://github.com/hipertracker/jspm-jsx-test. All ES6 syntax provided by Babel works, except JSX :(

hipertracker commented 9 years ago

BTW, Babel does not need floatdrop/plugin-jsx, because this plugin is not using Babel at all, it uses react-tools instead.

hipertracker commented 9 years ago

I found the source of problems with JSX. For unknown reason est6-module-loader put React on blacklist. This blocked JSX. I send a request to fix it https://github.com/ModuleLoader/es6-module-loader/pull/325

hipertracker commented 9 years ago

Patching es6-module-loader solved problems with JSX syntax but not in all cases. Bundling does not work with JSX. Still jspm bundle and jspm bundle-sfx do not recognize JSX :(

egauci commented 9 years ago

@hipertracker - I'm not sure if you were referring to my link when you said it was "not a jspm project". If you were, I assure you that it was indeed started with "jspm init".

Regarding enabling JSX in module loader, it appears to be against that project owner's policy: https://github.com/ModuleLoader/es6-module-loader/issues/311

hipertracker commented 9 years ago

That the same problem with es6-module-loader. jspm keep this file also at node_modules/jspm/node_modules/systemjs/node_modules/es6-module-loader/dist/es6-module-loader.src.js

hipertracker commented 9 years ago

Well, so that policy is just stupid. The owner can blacklist whatever he wants, but he should allow for overwriting it by the user. Why only 'react' is blacklisted but not 'flow', 'experimental', 'playground', 'loose' mode, etc.?

hipertracker commented 9 years ago

@egauci, that's weird. For me jspm init creates much more files than https://github.com/egauci/react-jspm-tests. E.g. it creates config.js file which is absolete in your repo...

egauci commented 9 years ago

@hipertracker - well, you have to "npm install jspm" then "jspm install". I only included sources.

(Sorry, I should have added a readme, but honestly I wasn't expecting anybody to see that project. It's just coincidence that you and I both came up on this JSX exclusion issue at the same time.)

johlrich commented 9 years ago

@hipertracker Your example project looks fine and you don't need to use gulp or any task runner to finish. In my project, I ended up utilizing the jspm jsx plugin @tritonrc mentioned and also don't use grunt/gulp/etc. I still use babel to manage the rest.

To build the bundle I execute jspm bundle-sfx app/main.jsx! dist/app.js --minify through npm scripts.

Granted, this technically doesn't allow you to use babel itself to do the jsx transformation since the plugin uses react-tools, but it does enable the workflow you're looking to enable with sourcemaps and all other goodness. I personally haven't found any issues with this approach. Is there a specific reason you need babel to handle the jsx transformation over react-tools?

hipertracker commented 9 years ago

@johlrich Using just Babel is simpler and more powerful. E.g. with that jsx plugin that code won't work:

async function foo() {
    await bar();
};
johlrich commented 9 years ago

@hipertracker Babel would still be used for all other transformations. As I mentioned, this is exactly how I am setup with the jsx plugin + babel. To get there in your project: jspm install jsx and change .js to .jsx, make sure they get passed through plugin first by using import App from './App.jsx!', turn on experimental: true in the babelOptions within config.js

hipertracker commented 9 years ago

@johlrich, it does not work. I can import only *.js files. I guess, this is enforced by default config.js settings:

// config.js:
System.config({
  "baseURL": "/",
  "transpiler": "babel",
  "paths": {
    "*": "*.js", // <-- here?
    "github:*": "jspm_packages/github/*.js",
    "npm:*": "jspm_packages/npm/*.js"
  }
});
// ...

I can change it "*": "*.js" into "*": "*.jsx" but

(1) I don't think it'd good idea to manipulate that file which can be overwritten to its default state by npm clean command,

(2) after that change all my files have to use .jsx extension only for ES6 imports.

And unfortunately, that change does not work for standard System.import command. When I use System.import('src/main.jsx!'); then the code is trying to download non existing http://localhost:3000/src/main.jsx.jsx.

UPDATED example: https://github.com/hipertracker/jspm-jsx-test

johlrich commented 9 years ago

@hipertracker I did not need to manipulate the paths. I cloned and used your repository just fine after switching the path entry back to "*": "*.js". Hello World for React 0.13.0-rc2 and some console output appears.

hipertracker commented 9 years ago

@johlrich You are right. Now all works. Thanks.

hipertracker commented 9 years ago

es6-module-loader fixed the problem blacklist. If jspm will be able to install the edge version of es6-module-loader, no jsx plugin is needed anymore.

hipertracker commented 9 years ago

Last news: es6-module-loader fixed the problem with blacklist. If jspm will be able to install the edge version of es6-module-loader, no jsx plugin is needed anymore.

johnsoftek commented 9 years ago

What happens when we no longer need a transpiler for ES6? The standard browser ES6 module loader will not likely not handle jsx syntax. Then we will need to re-instate a jsx transpiler.

On 10 March 2015 at 08:12, Jaroslaw Zabiello notifications@github.com wrote:

Last news: es6-module-loader fixed the problem with blacklist https://github.com/ModuleLoader/es6-module-loader/commit/4d0e42cbbf62274983f7764f3935060b6077048a. If jspm will be able https://github.com/jspm/jspm-cli/issues/580 to install the edge version of es6-module-loader, no jsx plugin is needed anymore.

— Reply to this email directly or view it on GitHub https://github.com/jspm/jspm-cli/issues/566#issuecomment-77955551.

egauci commented 9 years ago

@johnsoftek - I wouldn't worry too much about that:

1) 6to5 became Babel because they realized that development will never stop. There will always be something new that isn't yet implemented in your target environment.

2) You could keep babel just for the JSX.

hipertracker commented 9 years ago

It will take ages until all browsers support ES6/ES7. And I bet that some of them will support it better, some worse. Using transpiler like Babel is always better because it is browser independent, it works now, and it support not only JSX but even ES7.

For the same reason Polymer and web components are going into wrong direction. It will take ages until browsers adopt web components. It's much better to get away from the browser and it's problems towards pure JS and Virtual DOM. I like that ReactJS philosophy. it works now and it's browser independent.

johnsoftek commented 9 years ago

@egauci @hipertracker Good points. I agree with the aim of browser independence and even HTML independence. I like the way React insulates us from the real DOM. Too much of our browser app coding is influenced by the DOM, which is just one way of visualising components. React Native shows the benefit of having a layer between components and the render target .

zcregan commented 9 years ago

I had issues with the JSX plugin where React-Tools would error out on some valid ES6 syntax and so my JSX files never make it to Babel's ES6 transpiler.

I wrote my own JSX plugin using Babel instead of React-Tools for the actual JSX transpilation. Plugin: https://github.com/zcregan/plugin-babeljsx Demo: https://github.com/zcregan/JSPM-Babel-JSX-Demo

mrspeaker commented 9 years ago

I just want to add a +1 for hipertracker's solution: Babel supports jsx by default - so we shouldn't need any external plugins. But doing jspm dl-loader --edge is broken at the moment.

To test it out, create a clean project with jspm init, add React, then search for b.blacklist.push("react") in es6-module-loader.js in your project. Remove that expression, and jsx loading works as expected.

thylo commented 9 years ago

I had the same problem. I fixed it simply by updating the es6-module-loader to the latest version and by overwriting the blackilist setting as so :

<script>
    System.babelOptions = {experimental: true, playground: true, blacklist:[]};
    System.import('js/app');
</script>
anselmo commented 9 years ago

+1 for @thylo

System.babelOptions = {blacklist:[]}; 
egauci commented 9 years ago

@thylo @anselmo - definitely +1

Also works from config.js:

"babelOptions": {
   "optional": [
      "runtime"
   ],
  "blacklist": []
},
buxel commented 9 years ago

Has this problem been resolved? @egauci I dropped this config in an existing project but it still refuses to load .jsx files like @hipertracker described.

Are you sure .jsx works without further plugins? On a quick check on hipertrackers repo i found some references to jsx plugins, i.e. https://github.com/hipertracker/jspm-jsx-test/blob/master/config.js#L963

egauci commented 9 years ago

Yes @ChaosD, this works fine now. Make sure you have a recent version of jspm.

Here is a simple project I did: https://github.com/egauci/reord. It's using jspm 0.15.3.

I'm not even sure that the "blacklist: []" is still needed, but it doesn't hurt.

Oh, I don't name my files with a .jsx suffix, just .js. Since Babel transpiles everything, having different suffixes isn't needed, and would probably get in the way.

buxel commented 9 years ago

Thanks for the confirmation, i got something mixed up then. i was under the impression that it was supposed to load .jsx files if i import them like "foo.jsx!" Would have been sweet because some IDEs / Editors work nicer if they recognize the extension but i can live with that.

buxel commented 9 years ago

@egauci : one last follow up question: my IDE just annoys me too much when i have jsx syntax in .js files. I looked around for plugins to load .jsx files with jspm. There is floatdrop/plugin-jsx, whis has been deprecated in favour of babel. It also does not work anymore because react-tools has been removed

So: what is the current way of loading .jsx files when using jspm/systemjs ?

egauci commented 9 years ago

@ChaosD - I heard you about IDE issues with JSX. I (for now anyway) have switched to Atom - it has a decent JSX support through packages.

Anyway, sorry but I don't know the answer to your question. I think that JSPM is moving to not adding that extra '.js' at the end of suffixes it doesn't recognize in version 0.17, but I'm not sure I understand that correctly.

guybedford commented 9 years ago

The way to load jsx in jspm would be to use the package configuration defaultExtension option:

System.config({
  defaultJSExtensions: true, // this is overridden by the package config below
  packages: {
    // where [baseURL]/app is the local code
    'app': {
      defaultExtension: 'ts'
    }
  }
});

We can then import vendor/file and get vendor/flie.js and also import app/main and get app/main.jsx, while app/main.js will remain app/main.js.

buxel commented 9 years ago

@guybedford , did you mean to set defaultExtension to 'jsx'? Would make sense to me. Anyways, thanks for the clarification. Now I can have the best of both worlds :+1:

Edit: i just tried your solution and i cannot get it to work. What versions of jspm/babel are you using? Edit2: i just realized jspm fetches react 0.14-beta. Loading a react compinent (js extension) gives "Unexpected token: < ". Could it be because babel relies on react-tools for transpiling? I've read that they were removed.

Solved my problem, seems like my setup was somehow messed up. For anyone stumbling upon this, start over again and follow these steps, with "blacklist: []" in config:

mgenev commented 8 years ago

I'm having hte same problem where is the solution?

calbertts commented 8 years ago

What's the standard solution for this?

guybedford commented 8 years ago

I didn't realise this was still a catch. When a module is set as format: 'esm' JSX support is provided through Babel 5 normally. Otherwise use jspm install jsx and configure it as a loader.

calbertts commented 8 years ago

Thanks! it's clear now.

carlosdubus commented 8 years ago

Can't get JSX working with SystemJS. I installed jsx plugin. After that, I required main like this: System.import("admin/main.js!jsx");

The above worked with main.js containing JSX.

Then inside main I have:

var Nav = require('./components/nav.js!jsx');

var App = React.createClass({
    render: function() {
        return <Nav></Nav>;
    }
});

I get the following error when requiring Nav: Parse Error: Line 21: Unexpected token !

Any working examples I can look at? Thanks!

cchamberlain commented 8 years ago

@guybedford Is there a roadmap to the default babel transpiler getting bumped up to 6? I'm on 0.17.0-beta.14 trying to port a large webpack project to jspm and hit this issue.

guybedford commented 8 years ago

@cchamberlain jspm 0.17 uses Babel 6 through the SystemJS babel plugin. This can be installed via jspm install plugin-babel or through jspm init -p as the transpiler option.

adelespinasse commented 8 years ago

So it seems like the current way (with jspm 0.16.* anyway) is to install jspm-loader-jsx:

jspm install npm:jspm-loader-jsx

This is the only way I've managed to get it working. I didn't have to set the blacklist to []. I'm using the .js extension.

I learned about jspm-loader-jsx from this blog post after many hours trying other things and searching the web for help.

phoeniceus commented 8 years ago

We've had problems getting the jspm bundle command to transpile jsx files. I can display my web app using systemjs to transpile on the fly, but I cannot pre-bundle the files to plain javascript. I get unexpected token errors. More specifically, if I use...

JSPM v. 0.16.41 (the latest stable version) with Babel v.5

It throws "unexpected token" errors. But if I use...

JSPM v. 0.16.12 with Babel v.5

It works just like it says in [http://egorsmirnov.me/2015/10/11/react-and-es6-part5.html].

So I can see several possible ways for me to move forward but I don't know which way is best or even possible:

1) Use the older JSPM v. 0.16.12. I don't really want to do this as it forces me to stick with an out of date version of JSPM.

2) Use JSPM v. 0.16.41 with Babel 5 (the version it comes with) and spend hours figuring out how to make it work. Actually, I've already spent hours on this with no success. Anyone else?

3) Use JSPM v.0.16.41 and upgrade it to Babel 6. No idea how to go about this. Has anyone tried this? Can you give me instructions?

4) Move to JSPM v. 0.17. (beta version) which comes with Babel 6. I tried this but I couldn't even get my app to display without bundling. Too many other errors.

Any suggestions?

guybedford commented 8 years ago

@phoeniceus I followed the instructions there and it seems to work fine for me in 0.16:

Where test.jsx contains:

import React from 'react';
export var p = <div></div>;

Just let me know if I can help further.

phoeniceus commented 8 years ago

@guybedford The instructions on that page explicitly say to use version 0.16.12. (the first thing you type in the command prompt is "install -g jspm@0.16.12"). I want to find a way to make it work with the latest version, which is 0.16.41. If you install this latest version, does the bundle command still work?