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
Parcel 2 RFC #1952
Parcel 2 RFC #1952
Conversation
Is there going to be any SASS @ import support coming up? Just curious, it was something I ran into recently had to create a weird workaround. I think it was just so many partials in multiple entry points or something. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good level of detail. I left a couple of comments.
|
||
## Getting Started | ||
|
||
Before we get started, you'll need to install Node and Yarn (or npm) and create |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the minimum node version that is supported?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will always be whatever the lowest active LTS version of Node is.
"name": "my-project", | ||
"scripts": { | ||
"build": "parcel --production", | ||
"start": "parcel --serve" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using a postversion script for production builds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that is necessary for this guide
|
||
#### `--public-url <url>` | ||
|
||
[todo] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this implemented yet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been wanting to discuss this more with @devongovett cause it's sorta the odd flag out in the CLI
|
||
#### `--log-level <level>` | ||
|
||
Set the log level, either "0" (no output), "1" (errors), "2" (warnings + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would read cleaner to list these out:
Sets the log level (Default 2):
0
: No output1
: Errors2
: Warnings and Errors3
: All
|
||
### `package.json` | ||
|
||
[todo] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What needs to be added here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dunno, just needs a description
|
||
#### `--log-level <level>` | ||
|
||
Set the log level, either "0" (no output), "1" (errors), "2" (warnings + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a more detailed log mode? See #1834
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused about the difference between verbose
and debug
Is it dramatically different from parcel --verbose > parcel.log
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally debug printed a bunch more things like bundler options for example.
With the current implementation it is the same as parcel --verbose > parcel.log
except for the timestamp but that's just a slightly more complex command.
I still however think we should have both, but with Debug also having some more data like OS, Node Version, Parcel Version, Options, ... (unless that would be considered part of verbose)
So we instantly have all the information we need if anyone makes an issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I'd be happy to add another level above verbose, but I would argue that it shouldn't write to a file by default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, I agree it wasn't the best idea to spam the user with logfiles by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered the debug
module where you'd use literal names as a combination of filters in the DEBUG
envvar to introspect into individual modules and components? Ex., DEBUG=parcel:*
.
|
||
```json | ||
{ | ||
"browser": "distflinesof/browser/index.js" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a typo. Shouldn't it be dist/browser/index.js
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...indeed, wtf happened?
``` | ||
|
||
See [Aliases](#aliases) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we support externals? #144
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a good question, I think we need to talk about it a bit more.
One part of the problem I think belongs in aliases:
"aliases": {
"react": "https://unpkg.com/react@16.4.2/umd/react.production.min.js"
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome, however I'm not sure how that would work in practice as you can't reliably predict what parcel has to replace require('react')
or import 'react'
with as far as I know.
My main concern is probably that there is not really one standard for how to publish prebuilt packages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think aliases makes sense as along as you have a configuration for under what global name a package is exported and support packages which have only side effect. Maybe allow aliases to map to an object like this?
"aliases": {
"react": {
"url": "https://unpkg.com/react@16.4.2/umd/react.production.min.js",
"global": "React"
},
"datatables": {
"url": "//cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css",
"global": null
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mohsen1 That looks great to me. Ideally Parcel could handle falling back to a local module if the external one fails to load, rather than having to manually write the code for that (see my comment in #144 (comment)) but perhaps that's outside the scope of Parcel?
"main": "dist/main/index.js", | ||
"module": "dist/module/index.js", | ||
"browser": "dist/browser/index.js", | ||
"browserslist": ["> 1%", "not dead"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's already "common" to define "browserslist" as a top level property like this but it creates an inconsistency with the "engines" property. Does it make sense for "browsers" to be just another "engine"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we change what people are already doing they will just end up adding and maintaining both
|
Could you add the basic CLI commands for getting started in both Yarn and NPM? |
|
||
## Introduction | ||
|
||
Parcel is a compiler for all your code, regardless of the language or toolchain. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"all your code" sounds too broad, consider "all your web application frontend code".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parcel can also be used for back-end code, mainly node
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, then something like "web application frontend and Node.js-based backend code". It isn't so smart to build your Makefile-driven C++ server or a Ruby app, is it? (I'd hope it could, but alas)
P.S. Nevermind Ruby. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd like to keep our options open. :) Perhaps something like react native could be packaged with Parcel. The architecture has nothing JavaScript or even Web specific in it, so it should be possible to extend to any platform.
|
||
Configure the hot reloading port. | ||
|
||
#### `--[no-]source-maps` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#### `--source-maps`, `--no-source-maps`
for searchability by option name and similar to other boolean options.
output. Defaults to `package.json#source`, falling back to `src/index.*` or | ||
`index.*`. See [#Entries](#entries-sources-targets-environment). | ||
|
||
#### `--serve, -s` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put the option-separating commas outside of the backticks consistently?
- #### `--serve, -s`
- #### `--open, -o [browser]`
+ #### `--serve`, `-s`
+ #### `--open [browser]`, `-o [browser]`
#### `--cache <dir>`, `--no-cache`
#### `--hot`, `--no-hot`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see any mention of CSS modules in the Parcel 2 RFC. I'm curious if this is something the team is interested in. There is an open issue around CSS module support in parcel with a proposal for a zero-config option that would be nice to get feedback from the core team on if it is something that can be addressed in parcel 2.
@bjankord I think this might be a feature of |
What is a bundle exactly? Is it just a collection of arbitrary files (i.e. of different asset types)? |
@mmun Bundles should consist only assets of the same asset type. Although transforms can convert one asset type to another. |
|
||
There are some rules that should be followed across every type of plugin: | ||
|
||
- **Stateless** — Avoid any kind of state, it will likely be the source of bugs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some heavy transformers like FavIcon generator require caching to perform well. Do plugins get first class access to read/write cache managed by Parcel core?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cache will be handled by Parcel, as far as I know transforms won't have direct access to it. But every transform output will be cached.
It's more complex than cache every result
but it should be pretty optimised to never have to transform anything unless it changed (based on content hashes of the asset and deps)
yarn add --dev parcel | ||
``` | ||
|
||
From there you just need to point Parcel at some of your entry files. Like if |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding the getting started commands for NPM as well, the master branch of the README.md has both yarn and NPM. Was it a conscious choice to remove it?
Could do something like this
or with npm:
npm init
npm install -D parcel
@jamiebuilds Gotcha. How would you model optimizations across bundles? I'm thinking of something like inlining images into CSS. |
I imagine that would be best done in CSS compilers. I believe Sass does that already |
|
||
## Plugins | ||
|
||
### Resolvers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to confirm a resolver plugin can do what TypeScript module resolution spec describes.
|
||
See [Reporters](#reporters) | ||
|
||
## Parcel Architecture |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An in-memory FS was discussed before. Will Parcel 2 maintain an in-memory FS? Will plugins get access to that FS?
I'm asking because some tools like GraphQL codegen write .d.ts
TypeScript files to disk to make TypeScript happy about types. if the TypeScript compiler uses an in-memory FS and GraphQL writes to that you won't need to write to source directories to make the build pass
- `@parcel/transform-json` | ||
- `@parcel/transform-json5` | ||
- `@parcel/transform-less` | ||
- `@parcel/transform-posthtml` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how can one extend/configure the official transformers, or make use in their own plugins? for example, I want to rewrite some HTML tags with the posthtml transformer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parcel takes in an array of transforms, so they're chained so you can manipulate the output (of the previous transform) as much as you want.
ASTs are being sent from transform to transform, so if it's compatible you can re-use it (for performance).
Not sure why you'd ever wanna extend a transform, you could possibly re-use internals of another transform although that is probably risky as that's usually outside the scope of the transforms public interface and therefore not protected from change in minor releases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take the example, where I want to rewrite some tags in the html files. I assume parcel will use the ootb posthtml transformer for finding the referenced assets (CSS,JS). so I would just add my own transformer, based on posthtml, or traverse the AST myself? And add this to the transformer chain for HTML via API or config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no clue what ootb means, but this is how it would probably work.
.parcelrc
{
"extends": "@parcel/config-default",
"transforms": {
"*.html": ["@parcel/transform-posthtml", "parcel-transform-something"]
}
}
Parcel will run through it's own stuff collecting deps,... than parcel-transform-something
would run in the same thread on the same asset, with the output of the previous transform as it's input. You could traverse the ast to get some custom dependencies and I think you can also modify dependencies.
This is (sort of) how plugins work in posthtml as well, so it should be no different. Everything should be possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
great, this is what I would have expected. and of course this is all configurable via API as well, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API will also search for the parcelrc file or default config as far as I know.
It will also take an options object similar to the one parcel uses now but slightly different as you can see some cli flags are different in this RFC.
Not sure if you'll be able to provide a hardcoded parcelrc config.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if you'll be able to provide a hardcoded parcelrc config.
We want to use parcel as packager within our CLI tool, and ensure that certain transformers are present. with the 1.x version, we just register the asset types directly via API. so it would be important to be able to do the same for the transformers as well.
something along the lines of:
let tx = bundler.getTransformers('*.html');
tx.push(myCoolTransformer);
bundler.setTransformers('*.html');
(but maybe we should move this discussion into an issue)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to create a new issue, this is one big RFC for parcel 2.
So it's already in the right place.
The API should probably also be documented in this spec.
Will there be a standardised way for plugins to have a config inside |
I think this would be a counter productive choice since it would clutter up parcel specific configuration, since every tool should bring its own configuration. Maybe you should add your comment as review / request |
@mischnic this is kind of against what we are trying to do as far as I know. parcelrc just contains the plugins as described in this RFC, pretty sure it should not contain any plugin specific config. You might try to convince otherwise though |
Generally, I think this is a good decision, the used components and their configurations are cleanly separated (as opposed to the huge webpack config). But having loads of dotfiles (.babelrc, .postcssrc, .browserslistrc, cssnano.config.js, .posthtmlrc, .env, .mypluginrc) isn't a pretty solution either. |
This is generally a failure of file structure concept. Maybe that could solve some issue once every project tool would consider such an approach. |
@jbreckmckye not sure what you mean, it won't be possible to define anything else than plugins and transforms in parcelrc, it'll work pretty much the same as it does now. I'm pretty sure the config file should only be used whenever 2 plugins actually need to address the same filetype. Which is a very niche case anyways. |
Merged the RFC doc into master. Further comments can continue here, and any changes should be submitted as PRs. |
Is there an estimation or goal of when Parcel 2 will be ready to use? Can't wait! |
[View Rendered]
This RFC is written as documentation for the project, our documentation should
be detailed enough to work as a spec, and it's easier to write it once this way
than to approve a spec and start again on the documentation from scratch.
Everything in Parcel should be documented here, if it is not documented it will
not be part of Parcel 2.
Please let us know if you have any suggestions by commenting inline on the diff of this draft.
All feedback, from anyone, is welcome.