Open alexilyaev opened 4 years ago
Hey @alexilyaev , Sucrase itself runs fine in the browser (it doesn't have any node dependencies), though at the moment there's no pre-packaged browser build attaching it to the global scope, and there's no support for text/sucrase
-style scripts.
In the past, I've been hesitant about a browser bundle the attaches Sucrase as a global since it's kind of the "old way" of using libraries, though the text/sucrase
type of use case does seem compelling. In your case you'd just use the jsx transform, is that right? Seems like the typescript, flow, and imports transforms would only make sense in environments with additional tooling where you might as well have webpack (or similar) set up, though I could see a use case for TS/Flow checking and still wanting the script directly loaded to the browser rather than through webpack.
Well, my use case is teaching React with no bundler, currently it looks like this:
<div id="root"></div>
<script src="https://unpkg.com/react@16.12.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.12.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
<script type="text/babel" src="app.js"></script>
// app.js
const App = () => {
return <h1>Hello World!</h1>;
};
ReactDOM.render(<App />, document.querySelector('#root'));
So React is global.
import
and require
don't work in this context.
TypeScript would have been a nice addition as it useful for teaching.
Right now I'm only missing the React Fragment <>...</>
syntax support, which was added in babel-standalone v7.0.0-beta.31
...
I was using an old package of babel-standalone, the new one has the latest versions: https://unpkg.com/browse/@babel/standalone@7.8.4/
So this one does support the React Fragment syntax (and TS as well).
<script src="https://unpkg.com/@babel/standalone@7.8.4/babel.min.js"></script>
But, that file weighs 1.6 MB.
So, if sucrase
could do it leaner, I'd be happy about that.
duplicate of #506
BTW @alexilyaev, once this happens, you can use jsDelivr CDN to use only 1 request. Try this out instead of all your 3 unpkg
requests. though mine uses the current Babelv7.8.x & includes MaterialUI:
<script src="https://cdn.jsdelivr.net/combine/npm/react@16.12/umd/react.development.js,npm/react-dom@16.12/umd/react-dom.development.js,npm/@material-ui/core@4.8/umd/material-ui.development.js,npm/@babel/standalone@7.8/babel.min.js" crossorigin="anonymous"></script>
Note my versioning: Patch releases are auto-updated, but the Minor versions are fixed. Takes about 5 hits to your local POP before this concocted request is cached. Details: https://www.jsdelivr.com/features
@tomByrer That looks very interesting, I'll check it out, thanks!
@alangpierce Any extra consideration for a public standalone please? I'd love to use it via jsDelivr as I posted above.
@alexilyaev My link work for you? I've updated the versions successfully today.
@tomByrer Your link does work, nice one liner.
For the training I eventually downloaded the files via npm and linked to them in the example files. Even managed to add MobX with Decorators support, which I was very happy about. In that sense, Babel does provide quite a bit of flexibility.
<body>
<div id="root"></div>
</body>
<script src="../../../../node_modules/react/umd/react.development.js"></script>
<script src="../../../../node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="../../../../node_modules/mobx/lib/mobx.umd.js"></script>
<script src="../../../../node_modules/mobx-react-lite/dist/index.js"></script>
<script src="../../../../node_modules/mobx-react/dist/mobxreact.umd.development.js"></script>
<script src="../../../../node_modules/@babel/standalone/babel.min.js"></script>
<script>
/**
* This is only needed for this training course, to be able to write modern JS
* without running a build/bundler.
*/
const Babel = window.Babel;
/**
* Configure @babel/standalone transformations:
* https://babeljs.io/docs/en/babel-standalone
*/
Babel.registerPreset('ai-react', {
presets: [
// Enable legacy decorators for MobX
// https://babeljs.io/docs/en/babel-preset-stage-2
[Babel.availablePresets['stage-2'], { decoratorsLegacy: true }],
Babel.availablePresets.react
],
plugins: [
// Map package imports to their global namespaces
// https://babeljs.io/docs/en/babel-plugin-transform-modules-umd
[
Babel.availablePlugins['transform-modules-umd'],
{
globals: {
react: 'React',
'react-dom': 'ReactDOM',
'mobx-react': 'mobxReact',
'mobx-react-lite': 'mobxReactLite'
},
exactGlobals: true
}
]
]
});
</script>
<script
type="text/babel"
data-plugins=""
data-presets="ai-react"
src="app.js"
></script>
For my use case it's good enough. But I can imagine some online editors wanting to use sucrase in the browser and babel being too big for them.
@alexilyaev can you try importing from pika CDN?
import * as sucrase from 'https://cdn.pika.dev/sucrase'
@alexilyaev can you try importing from pika CDN?
import * as sucrase from 'https://cdn.pika.dev/sucrase'
I didn't understand how does that help me achieve what babel-standalone
is doing?
Looking at my code example above, where would I fit that line?
And how would it map import React from 'react';
in my app.js
?
Example app.js
that needs to work in the browser:
import React from 'react';
import ReactDOM from 'react-dom';
const root = <button className="btn-primary">Click me!</button>;
ReactDOM.render(root, document.querySelector('#root'));
Here an example on how you can setup sucrase to work in the browser using a service worker: https://gist.github.com/nestarz/dcaa70b5ecac5fa7e66103658f7ff0b7
The caveat is that I copied paste the code (from skypack) of sucrase inside the sw.js.
I would be interested in a browser build for Sucrase that introduces a global. My use case is a browser-based code editor. I have it up and running using Buble, but looking to migrate to Sucrase as Buble does not support optional chaining (and Buble has tons of unused stuff for transforming ES6).
Here's an example of where it would be used:
https://vizhub.com/curran/c3b14112dae34ef395999cef5783324f?edit=files&file=index.js
In the past, I've been hesitant about a browser bundle the attaches Sucrase as a global since it's kind of the "old way" of using libraries
Indeed, it's the "old way", but IMO it's fine. Lots of things still operate the "old way" with script tags and browser globals, and it's a tried and true approach. Also, what are the downsides of introducing a new dist file? Not many. It poses no risk of breakage.
It'll be nice if Sucrase could include a UMD or IIFE version in release. Then we'll be able to use it directly via importScripts
in Service Workers.
I'm writing an on-the-fly build tool using Service Worker, whose goal is to rid of node completely for modern frontend development/production, and I'm finding an alternative to esbuild since it could go out of stack strangely in Safari, but lacking of UMD/IIFE support won't make me able to create a plugin for Sucrase.
Currently there's only a CJS version and https://bundle.run/sucrase could do nothing about it.
I agree.
It seems this work was done already here https://github.com/alangpierce/sucrase/pull/526
That PR was closed in favor of using
import * as sucrase from 'https://cdn.pika.dev/sucrase@3.14.0'
, but I think it would be great to include a browser build with the Sucrase package distribution directly, rather than introduce a dependency on a third party service/CDN.
What's making things worse is that these CDNs are all serving only ESM, while import
in Service Workers still require quite modern Chrome to be functional.
I'm proposing that a UMD build be created for use over CDNs, not the ESM build.
For what its worth, I tried building sucrase with Rollup and IIFE in https://github.com/altbdoor/sucrase-build-iife#usage
I mostly followed the existing work in #526 , with minor adjustments to make things work. I managed to get things work in a service worker, to compile JSX to JS.
Very nice! I could imagine this going into mainline Sucrase as an additional npm script that runs on prepublish:
npx rollup -i ./package/dist/index.js \
-f iife \
-n sucrase \
--banner "/* sucrase v$VERSION */" \
-p '@rollup/plugin-node-resolve' \
-p '@rollup/plugin-commonjs' \
-p '@rollup/plugin-terser' \
-o dist/sucrase.browser.js
From your work in https://github.com/altbdoor/sucrase-build-iife/blob/master/.github/workflows/build.yml#L79C1-L86C39
For the same reasons babel-standalone exists. Would be nice to be able to run sucrase in browser code.
e.g.
Right now babel-standalone doesn't support React Fragments (it's stuck on babel v7 beta 3).