-
Notifications
You must be signed in to change notification settings - Fork 75
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
create-crank-app #94
Comments
I don't know where to put this in a PR (I think probably import { mkdir, writeFile } from 'fs/promises';
import { fileURLToPath } from 'url';
import { dirname, basename } from 'path';
import { spawn } from 'child_process';
function die(error) {
console.error(error);
process.exit(1);
}
process.on('unhandledRejection', die);
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageName = basename(__dirname);
const packageJson = {
name: packageName,
version: "1.0.0",
}
async function writeJson(filename, obj) {
return writeFile(filename, JSON.stringify(obj, null, 2) + "\n", 'utf8');
}
async function spawnPromise(cmd) {
const child = spawn(cmd, {shell: true});
for (const pipe of ["stdout", "stderr"]) {
child[pipe].setEncoding('utf8');
child[pipe].on('data', data => process[pipe].write(data));
}
return new Promise((resolve, reject) => {
child.on('close', code => {
code ? reject() : resolve();
});
});
}
const html = `<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<script src="index.js"></script>
</body>
</html>
`;
const js = `/** @jsx createElement */
import {createElement} from "@bikeshaving/crank";
import {renderer} from "@bikeshaving/crank/dom";
function Greeting({name = "World"}) {
return (
<div>Hello {name}</div>
);
}
renderer.render(<Greeting />, document.body);
`
const gitignore = `.cache
dist
node_modules
`;
void async function() {
await writeJson('package.json', {
name: packageName,
version: '1.0.0',
scripts: {
start: "parcel index.html --open",
build: "parcel build index.html",
}
});
await spawnPromise('npm install @bikeshaving/crank');
await spawnPromise('npm install --save-dev parcel-bundler');
await Promise.all([
writeJson('.babelrc', {presets:['@babel/preset-react']}),
writeFile('index.html', html, 'utf8'),
writeFile('index.js', js, 'utf8'),
writeFile('.gitignore', gitignore, 'utf8'),
]);
await spawnPromise('npm run build');
console.log("Now you can `npm run start` to view your Crank app in a browser.");
}(); |
Possible enhancements:
|
IIRC npm init foo bar is equivalent to node /path/to/create-foo bar? Entry point is the "bin" property in /path/to/create-foo/package.json, forwarding the arguments unchanged. Like, process.argv[2] should contain the dirname, and you fall back to process.cwd() if it's undefined. What do you win by using pipes and async apis in a one-off script, if you don't modify output or parallelize commands? |
I do parallelize some of the commands, though, admittedly, not any of the spawns. (I thought I was going to, and then decided not to.) |
I figured out how to test
Nonetheless, I think the next step is for there to be a github repo for |
Preact cli does more than we need to out of the box (especially for the first iteration of this) but it's a great place to look for inspiration:
They keep their cli templates here |
I’m investigating snowpack and think it could potentially be revolutionary. I’ve been dissatisfied with all the major bundlers and the features/philosophical clarity of snowpack version 2 is something I admire. |
Snowpack looks really cool, but Snowpack 2 is not in a good place right now. I couldn't get even the most basic Babel/JSX transpilation to work this afternoon. FredKSchott/snowpack#294 |
@dfabulich Yes as I investigate it seems like it uses both rollup and parcel under the hood somehow? 😨 |
@dfabulich do you enjoy finding build/environment bugs because you seem to be very good at it haha. |
every time I go to try a new bundler/build tool in the JS world I always end up going back to webpack for bundling applications (js + css + html + assets). they have a few sane defaults and if you keep the config simple, it's not horrible and will do what you expect. I'd highly suggest we use webpack for create-crank-app :) |
Apparently the Vue.js Vite project supports preact as well. https://twitter.com/youyuxi/status/1257882133177274369 I really do like the idea of no transpilation for development. I can never ever seem to get sourcemaps/errors working 100% and it seems like it could be a lovely development experience. @ryhinchey If you snoop around https://github.com/bikeshaving/crank/blob/master/website/webpack.tsx?ts=2 you’ll see that I sorta attempted to create a bundler API which is defined entirely with components. The fact that components on the server can be async today means we can do stuff like this, and a lot of bundler configuration complexity stems from trying to get scripts to match the bundler output. If there was a bundler that had a clear and promise-fluent API which was like... you pass in a local file path and it compiles it for you and it spits out information about the bundle, we could actually get a sort of zero-config type of bundling system where you can just use enhanced versions of script and style tags to both kick off rendering and render html on the server. |
I'm not sure if the complications described above came from trying to leverage Babel, but I was able to get the basics going with Snowpack 2 and just using the Typescript TSX compiler. Here is the gist with relevant app files and Snowpack configuration. I started with the Snowpack blank template. The only thing that doesn't work is HMR. The HMR triggers, but module code is not refreshed. Looking at some of the plugins, it looks like each framework as their own way to register modules with Snowpack. I'm new to looking into the HMR internals. But it would seem that some sort of HMR plugin would need to be built specific to Crank. These plugins don't seem overly complex to write, but they are not trivial. I'll keep looking into it and see if how hard it would be to create a Snowpack plugin for managing the HMR process. Fast React issue which describes the Fast React implementation. |
Setting up JSX and a module bundler can be kinda tricky. If you create an npm project starting with
create-
, e.g.create-blah
you can typenpm init blah
, which is equivalent tonpx create-blah
.https://docs.npmjs.com/cli/init
https://github.com/facebook/create-react-app is the most famous of these, and infamously has a ton of complicated features. I would also call attention to Stencil's initializer https://github.com/ionic-team/create-stencil which is still pretty complicated, but it's not as bad.
The text was updated successfully, but these errors were encountered: