Complex WebPack configurations have long been a sore point in front-end projects, and the new generation of “zero-configuration” packers called Parcel is addressing this problem. In the days since Spring Festival, I’ve been trying to migrate my business to a Parcel build. Here are some of my missteps.

First the conclusion:

  • Parcel is perfect for packaged builds of small, single-page React pages, and is literally zero configuration
  • For vue, there are currently some craters in parcel-plugin-vue (see this issue for details) that have been fixed, but parcel-plugin-vue is not yet updated.
  • For large multi-page projects, parcel packaged builds are fine, but Parcel 1.6.2 currently doesn’t support CommonsChunk and Tree Shaking, and alias support won’t come until the next release, so the js built is quite bulky.

Quick learning

Start with a simple React application. Install it first:

npm i parcel-bundler -g
Copy the code

Then you can write a React Hello World:

<! -- index.html --> <html> <body> <div id="root"></div> <script src="./index.js"></script> </body> </html>Copy the code
// index.js import React from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render( <h1>Hello, parcel! </h1>, document.getElementById('root') );Copy the code

We use ES6 syntax here, as well as JSX, but unlike WebPack, we don’t need to configure a bunch of extra Loaders and plug-ins, and we don’t need to differentiate build configurations for development/production environments.

In order for this ES6/JSX code to work, you just need to install some Babel plugins:

npm install babel-preset-env
npm install babel-preset-react
Copy the code

Then write a.babelrc:

{
  "presets": ["env", "react"]
}
Copy the code

Then, you can run a native development environment with HMR, ES6/JSX syntax, and other advanced features:

parcel index.html
Copy the code

For common images, less files, etc., parcel is naturally supported and doesn’t require any configuration:

Import yourImage from '123.png'; Import 'index.less'; ReactDOM.render( <img src={yourImage} />, document.getElementById('root') );Copy the code

The build is also simple:

parcel build index.html
Copy the code

Use Parcel to build Vue projects

React differs slightly from React by installing an additional package-plugin-vue to support loading of.vue files:

npm i parcel-plugin-vue
Copy the code

And then it’s very simple:

<! -- index.html --> <html> <body> <div id="root"></div> <script src="./index.js"></script> </body> </html>Copy the code
// index.js
import Vue from 'vue'
import App from './index.vue'
new Vue({
  el: '#root',
  render: h => h(App)
})
Copy the code
<! -- index.vue --> <style lang="less" scoped> div { font-size: 50px; text-align: center; } </style> <template> <div>hello {{text}}! </div> </template> <script> export default { data() { return { text: 'parcel' } } } </script>Copy the code

Run:

parcel index.html
Copy the code

Here we use.vue files, which contain the less dialect, es6 syntax, and require no additional configuration.

Some potholes in the VUE project

Uncaught TypeError: Cannot read property ‘add’ of undefined

Our example above uses parcel 1.6.2 and package-plugin-vue 1.5.0, and it is possible to encounter this error, which is essentially caused by falsely overwriting one of the methods of parcel in package-plugin-vue, It has now been fixed (see this issue for details), but the new version of the fix has not been released yet and may take a few more days.

Error Unknown Version 6.2 of Samsung

In some older projects, this may be caused by the old version of Caniuse-Lite that browserList relies on. Updating Caniuse-Lite can fix this:

npm i caniuse-lite
Copy the code

Correct posture for using a parcel in production

1. Local development environment

Parcel opening the development environment is simple:

parcel xxx.html
Copy the code

But in most projects, we prefer to use intra-project installed parcels rather than globally installed parcels, so we’ll write an NPM script and then NPM run dev:

{
    "scripts": {
        "dev": "parcel xxx.html"
    }
}
Copy the code

However, there may be multiple pages in the project, and it would be troublesome to write one NPM scripts for each page, so we can use the parameters of NPM scripts to solve this problem:

{"scripts": {"dev": "parcel"}}Copy the code

then

npm run dev -- /path/to/xxx.html
Copy the code

Note — there is a space between and the path so that NPM recognizes the path as a parcel argument.

2. Construction of multi-page projects

Parcel does not currently support multiple entries, so it can only be built page by page, which we can solve automatically with shell scripts.

For example, our project structure looks like this:

SRC ├─ page1 ├─ index.html ├─ page2 ├─ index.html ├─ page3 ├─ index.html ├─ ├─ ├─ index.txt ├─ index.txtCopy the code

So we can write a build.sh as a build script:

Dist rm -rf dist mkdir dist CD./ SRC /page for name in $(ls) do echo building $name . npm run parcel:build -- src/page/$name/index.html -d dist/$name --detailed-report doneCopy the code

Notice that we used the command parcel:build:

{
    "scripts": {
        "parcel:build": "parcel build"
    }
}
Copy the code

A summary of the pros and cons of building with Parcel

Advantages:

  • Zero configuration is really cool, cool is cool, use will never come back, completely say goodbye to hundreds of lines of complex Webpack configuration.
  • It builds much faster than WebPack and has a lot of stuff built in that webPack is a pain in the ass (like HMR, Dev Server, various Loaders).
  • It can fully cope with the development and construction of large projects.

Disadvantages:

  • Some advanced features of WebPack are not supported, such as CommonsChunk, Tree Shaking, multi-entry files, custom built filenames, inline small images, inline CSS, etc., so the built resources are quite large.
  • Currently, building large projects requires additional shell scripting (but I really find it much easier than writing webpack builds).
  • It is still in the rapid iteration period. In special cases, there may be strange errors, which need to be solved by debugging.