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

Allow to specify the invocation options in the entry point JavaScript file #49

Open
zindel opened this issue Feb 18, 2018 · 7 comments
Open

Comments

@zindel
Copy link
Member

zindel commented Feb 18, 2018

Problem

Currently, fastpack only allows to specify the configuration using the command line options interface. This works, but gets clunky very quickly, especially with several preprocessor options. Consider, for instance the command line required to pack the CRA-based application with fastpack:

$ fpack src/index.js --dev --output=dist --preprocess='^src.+\\.js$' --preprocess='\\.svg$:url-loader' --preprocess='\\.css$:style-loader!css-loader?importLoaders=1!postcss-loader?path=postcss.config.js'

As you can see, it quickly becomes unmaintainable as well as requires a lot additional quotation according to shell rules.

The obvious solution here is to add the config file. We would like to avoid it for the first release for a couple reasons:

  1. We are not settled on the config file format, all considered ones had their own disadvantages (JSON for example is quite verbose and still requires some quotation)
  2. Maintaining the completely alternative way of invocation requires a lot of resources.
  3. We like the cmdliner for its "ease of use" and prefer config to be using it as much as possible.

But still, we want to somehow improve the user experience when using fastpack.

Proposal

What if we allow to specify these invocation options in the entry point JavaScript file in a pragma-like comment. Here is and example above converted and included into the src/index.js:

/* fastpack
This is inline comment describing the option if needed
--dev
--output=dist
--preprocess=^src.+\.js$
--preprocess=\.svg$:url-loader
--preprocess=\.css$:style-loader!css-loader?importLoaders=1!postcss-loader?path=postcss.config.js
*/
/* the rest of code */

And here is the invocation:

$ fpack src/index.js

Couple things to note:

  1. Configuration section starts with /* fastpack and ends with */ on the separate line
  2. Inside the configuration section all lines not starting with -- are ignored
  3. Each considered line starts with -- and then follows usual command-line option format
  4. No additional quotation is needed, consider --preprocess=^src.+\.js$ vs --preprocess='^src.+\\.js$'
  5. That said, specifying of positional arguments is impossible and this is fine, since the only positional argument is an entry point itself, which is already known, since we're reading this file.
  6. All paths are resolved relative to the package root directory, not the entry point itself, i.e. output directory in the example above will be ./dist, not ./src/dist.
  7. We would expect the configuration section to go in the file header, but that is not necessarily a requirement, technically it can go anywhere in the file.
  8. Only one configuration section is expected, we will error out if we find more.
  9. The only configuration section considered is the one appears in the entry point file. All other configuration sections met in the dependency tree are treated as the regular JavaScript comment and ignored for configuration purposes.

This design also enables us to easily differentiate between development and production builds, permitting easier configuration and adding polyfills in the separate entry point file. For example:

index.js

/* fastpack
configuration used in development
*/
// the entry point of the app

index.prod.js

/* fastpack
configuration used in production
*/
import 'babel-polyfill'; // or some other one
import './index';
@rauanmayemir
Copy link

I can't comment on fastpack's current workflow as I haven't used it long enough to appreciate its ease of use or feel any pain. I can, however, describe what I wouldn't like and what I'd consider 'nice':

  1. I definitely don't like pragma approach. If I'm not using fastpack universally (read: for both dev and prod envs), I don't see a point to include it in source code. (Even if we get to the point where we use fastpack for everything, I'd still feel reluctant to 'pollute' source code)
  2. I'd consider any of Fastpack.toml, Fastpack.yml, .fpackrc nice. I agree that json would be lacking for requiring quotation and escaping.

@TrySound
Copy link
Member

Yeah, config is better. At least package.json field.

@zindel
Copy link
Member Author

zindel commented Feb 18, 2018

Ok, how about the same approach, but in the config file?

@rauanmayemir
Copy link

Like this?

% cat fastpack.conf

--dev
--output=dist
--preprocess=^src.+\.js$
--preprocess=\.svg$:url-loader
--preprocess=\.css$:style-loader!css-loader?importLoaders=1!postcss-loader?path=postcss.config.js

It doesn't look very friendly and I'm not sure it warrants bringing in a separate config layer.

I'm contemplating with two approaches:

  1. Keep everything as command-line options with a possibility to set ENV vars. Delay bringing in the config file as long as possible to have more time for features and config areas to shape up.
  2. Bring the config in but risk having it constantly change its format.

@TrySound
Copy link
Member

@zindel
Copy link
Member Author

zindel commented Feb 18, 2018

@rauanmayemir @TrySound thank you for your feedback!

I, personally, don't see it as non-nice approach (in fact, we have seen it used in stack). Although, I see your points and from alternatives you've listed I like *.toml or *.ini files used in Flow.

Keep everything as command-line options with a possibility to set ENV vars. Delay bringing in the config file as long as possible to have more time for features and config areas to shape up.

That's definitely what we're trying to achieve with the block comment in the entry point, but the argument with code pollution is legitimate - no one likes the intrusive software.

@zindel
Copy link
Member Author

zindel commented Feb 19, 2018

I'm removing the "first release" badge from this one. It seems it requires a little bit of a discussion before making the final decision. In the meantime we would recommend using shell files and provide some examples in the documentation.

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

No branches or pull requests

3 participants