Parcel Tutorial For Beginners 2019

Parcel Tutorial from Coding compiler. Parcel is a web application packaging tool for developers with different experiences. It utilizes multi-core processing to provide extremely fast speeds and does not require any configuration.

ParcelJs Tutorial – Getting Started with Parcel

First install Parcel via Yarn or npm:

Yarn:

yarn global add parcel-bundler

Npm:

npm install -g parcel-bundler

Create a package.json file in the project directory you are using:

yarn init -y

Or

npm init -y

Parcel can use any type of file as an entry, but it’s best to use an HTML or JavaScript file. If you introduce a main JavaScript file with a relative path in HTML, Parcel will also process it to replace it with the URL of the output file.

Next, create an index.html and index.js file.

 <html>
<body>
 <script src="./index.js"></script>
</body>
</html>
console.log("hello world");

Parcel has a built-in development server that automatically rebuilds the application when you change the file, and for rapid development, the development server supports hot module replacement . Just need to point out in the entry file:

parcel index.html

Now open https://localhost:1234/ in your browser . You can also use the -p <port number>option to override the default port. If you don’t have your own server, you can use the development server, or your application is completely rendered by the client. If you have your own server, you can watchrun Parcel in mode. It will still automatically rebuild and support hot swap when the file changes, but will not launch the web service.

parcel watch index.html

When you are ready to create in production mode, the build mode will turn off listening and only once. Please check the Production for more details.

Parcel Resources (Assets)

Parcel is resource-based, resources can represent arbitrary files, and Parcel has more support for JavaScript, CSS, and HTML files. Parcel automatically analyzes the dependencies referenced in these files and packages. Resources of the same type are combined into the same bundle. If you import other types of resources (for example, if you import a CSS file in a JS file), Parcel will launch the sub-bundle and keep a reference to it in the parent bundle. This will be explained in the following sections.

JavaScript

JavaScript is the most traditional type of web packaged file. Parcel supports both CommonJS and ES6 module syntax to import files. It also supports dynamic import()function syntax asynchronous loading module, it will be in the code split is discussed section.

// Import modules using CommonJS syntax
const dep = require('./path/to/dep');

// Import modules using ES6 syntax
import dep from './path/to/dep';

image files. When importing such files, Parcel does not inline the file like any other packaging tool, but instead places all dependencies in another bundle (for example: a CSS file).

When using CSS Modules , this exported class will be placed in a JavaScript package. The other resource files will be exported as URLs to the output in the JavaScript package so that they can be referenced in your code.

// Introducing CSS files
import './test.css';

// Introducing CSS files containing CSS modules
import classNames from './test.css';

// Import images as URLs
import imageURL from './test.png';

If you want to replace the URL import file with an inline file to a JavaScript package, you can use the Node.js fs.readFileSync API. The URL must be statically analyzable, meaning that it cannot have any variables (except for __dirnameand __filename).

import fs from 'fs';

// Read content as a string
const string = fs.readFileSync(__dirname + '/test.txt', 'utf8');

// Read content as a Buffer
const buffer = fs.readFileSync(__dirname + '/test.png');

CSS

JavaScript files or HTML files can be imported CSS resources, and through @importgrammar references dependence, but also by url()the function introducing images, fonts, and so on. Other by @importimported files are inline CSS to CSS with a bag, and url()references to rewrite its output file name. All file names should be associated with the current CSS file.

/* Introduce other CSS files */
@import './other.css';

.test {
 /* Reference image file */
 background: url('./images/background.png');
}

In addition to the normal CSS, other CSS preprocessor languages ​​such as LESS, SASS, and Stylus are also supported, and the execution method is the same.

SCSS

SCSS need to compile node-sassthe module via npm install it:

npm install node-sass

Once installed node-sass, you can import SCSS files into your JavaScript files.

import './custom.scss'

SCSS file dependencies can use @importstatement.

HTML

HTML resources are provided to Parcel’s common entry files, but can also be referenced by JavaScript files, such as providing links to other pages. Extract and compile URLs for scripts, styles, media, and other HTML files as described above. References are overridden in HTML to link to the correct output file. All file names should be associated with the current HTML file.

<html>
<body>
 <!-- Introducing image files -->
 <img src="./images/header.png">

 <a href="./other.html">Link to other pages</a>

 <!-- Introducing a JavaScript bundle -->
 <script src="./index.js"></script>
</body>
</html>

Parcel Transformations

Many packaging tools require you to install and configure plugins to convert resources. Parcel supports many out-of-the-box converters and built-in compilers. You can use Babel to convert JavaScript, PostCSS to convert CSS, and PostHTML to convert HTML. Parcel automatically runs and converts when it finds a configuration file (for example, .babelrc , .postcssrc) in the module.

This can even be a third-party node_modulesrun: If the configuration file was posted as part of the package, then only the module automatically enable conversion. Since you only need to process the modules that need to be converted, you can quickly package them. This also means that you don’t need to manually configure the transformation to include and exclude certain files, and you don’t need to know how to build third-party code to use it in your application.

Babel

Babel is a popular JavaScript converter with a large plugin ecosystem. Babel works with Parcel in the same way that it is used alone or with other packaging tools.

Install presets and plugins in your application:

yarn add babel-preset-env

Next, create one .babelrc:

{
 "presets": ["env"]
}

PostCSS

PostCSS is a tool for converting CSS using plugins, such as autoprefixer , cssnext, and CSS Modules . You can create a configuration using one of these names to achieve the purpose of configuring PostCSS with Parcel: .postcssrc(JSON), .postcssrc.js, or postcss.config.js.

Install plugins in your application:

yarn add postcss-modules autoprefixer
Next, create a .postcssrc file:
{
 "modules": true,
 "plugins": {
   "autoprefixer": {
     "grid": true
   }
 }
}

Plugins in plugins the specified object as key, and use the value of an object definition options. If the plug is no option, just set it trueto.

You can .browserslistrc specify autoprefixer, cssnext and target browser other tools:

> 1%
last 2 versions

Use top modules key, CSS module enables a slightly different way. This is because Parcel needs special support for CSS modules because they also export an object that is included in the JavaScript package. Please note that you still need to install it in your project postcss-modules.

PostHTML

PostHTML is a tool for converting HTML through plugins. You can create a configuration using one of these names to achieve the purpose of configuring PostHTML with Parcel: .posthtmlrc (JSON) , posthtmlrc.js, or posthtml.config.js.

Install plugin in your application:

yarn add posthtml-img-autosize
Next, create one .posthtmlrc:
{
 "plugins": {
   "posthtml-img-autosize": {
     "root": "./images"
   }
 }
}

TypeScript

TypeScript is a superset of JavaScript types that can be compiled into plain JavaScript and also supports the features of modern ES2015+. Converting TypeScript requires no extra configuration and is ready to use right out of the box.

 <!-- index.html -->
<html>
<body>
 <script src="./index.ts"></script>
</body>
</html>
// index.ts
import message from "./message";
console.log(message);
// message.ts
export default "Hello, world";

Parcel Code Splitting

Parcel supports zero configuration code splitting and is out of the box. This allows you to split the application’s code into separate packages that can be loaded on demand, which means smaller initial package sizes and shorter load times. As the user needs to load the corresponding module in the application, Parcel will automatically be responsible for loading the sub-bundle on demand.

When the code is resolved by the use of dynamic import()function syntax proposal controlled, the proposal with the general import statement or require similar function, but returns a Promise object. This means that the module is loaded asynchronously.

The following example shows how to use dynamic import to load a subpage of an application on demand.

 // pages/about.js
export function render() {
 // Render page
}
import('./pages/about').then(function (page) {
 // Render page
 page.render();
});

Because import()returns a Promise, so you can also use the async / await syntax. However, before the browser can support it extensively, you may need to configure Babel to convert the syntax.

const page = await import('./pages/about');
// Render page
page.render();

Dynamic load Parcel may be delayed import, so you still need all the import()calls placed on top of the file, and before using the sub-bundles, they will not be loaded. The following example shows how to dynamically delay loading a subpage of an application.

 // Set the page name to the dynamically imported map.
// These pages will not be loaded until they are used.
const pages = {
 about: import('./pages/about'),
 blog: import('./pages/blog')
};

async function renderPage(page) {
 // Lazy loading request page.
 const page = await pages[page];
 return page.render();
}

Note: If you still want to use does not support the syntax async / await in the local browser, remember that your application needs to introduce babel-polyfill or introduce in your library babel-runtime+ babel-plugin-transform-runtime.

yarn add babel-polyfill
import "babel-polyfill";
import "./app";

Hot Module Overload (HMR)

Hot Module Reload (HMR) automatically updates the module optimization development experience in the browser at runtime without having to refresh the entire page. This means that the state of the application can be preserved when your code changes slightly. Parcel’s HMR implementation supports out-of-the-box JavaScript and CSS resources. HMR is automatically disabled when it is built in production mode.

When you save the file, Parcel recompiles the changed content and sends an update containing the new code to any running client. The new code will replace the old version of the code and re-evaluate with all parents (Translator’s Note: This sentence is a bit strange to translate, everyone has a better translation welcome PR).

You can module.hothook this procedure using the API, and writing this code will notify you when you process the module or when a new version comes in. A similar project, react-hot-loader, can help you with this process and get it out of the box with Parcel.There are two known methods: module.hot.accept and module.hot.dispose. You can call module.hot.accept and give a callback function that executes when the module or other dependencies are updated. The module.hot.dispose callback function is called when the module is about to be replaced .

if (module.hot) {
 module.hot.dispose(function () {
   // When the module is about to be replaced
 });

 module.hot.accept(function () {
   // When the module or one of its dependencies has just been updated
 });
}

Safe Write

Some text editors and IDEs have Secure write features that basically prevent data loss by getting a copy of the text and renaming it when it is saved.

This feature prevents automatic detection of file updates when using Hot Module Overload (HMR). To disable it Secure write, use the options provided below:

  • Sublime Text 3 Add atomic_save: “false” to your user settings.
  • IntelliJ Use search in the settings to find “safe write” and disable it.
  • Vim Add: set backupcopy=yes to your settings.
  • WebStorm Uncheck the “safe write” option in Preferences > Appearance & Behavior > System Settings.

Production Environment (Production)

When you need to bind an application, you can use the production mode of Parcel.

parcel build entry.js

This will turn off listening mode and hot module replacement, so it will only compile once. It also turns on the minifier to reduce the size of the output package file. The minifiers used by Parcel are JavaScript uglify-es , CSS cssnano and HTML htmlnano .

Start the production mode and also set the environment variables NODE_ENV=production. Large libraries like React, which only use development debugging, can be built smaller and faster by setting this environment variable to disable debugging.

Options

Set the output directory

Default: “dist”

 parcel build entry.js --out-dir build/output
or
parcel build entry.js -d build/output
root
- build
- - output
- - - entry.js

Set the public URL to serve

Default: –out-dir option

parcel build entry.js --public-url ./

Will output to:

<link rel="stylesheet" type="text/css" href="1a2b3c4d.css">
or
<script src="e5f6g7h8.js"></script>

Disable compression

Default: minification enabled

parcel build entry.js --no-minify

Disable file system caching

Default: cache enabled

parcel build entry.js --no-cache

How Does Parcel Work?

Parcel The resource converting trees into a bundle tree. Many other packaging tools are basically based on JavaScript resources, as well as resources in other formats attached to them. For example, inline a string into a JS file. Parcel is non-aware of file types, works with any type of resource as you would expect, and does not need to be configured. Parcel’s packaging process has three steps.

1. Build a resource tree

Parcel accepts a single entry resource as input and can be of any type: a JS file, HTML, CSS, images, and more. There are many different resource types defined in Parcel that know how to handle specific file types. Resources are parsed, resource dependencies are extracted, and resources are converted to the final compiled form. This process creates a resource tree.

2. Build a bundle tree

Once the resource tree is built, the resources are placed in the bundle tree. First, an entry will be created as a resource bundle, then the dynamic import()will be created as a sub-bundle, which led to the split of the code.

When different types of file resources are introduced, the sibling bundle is created. For example, if you introduce a CSS file in JavaScript, it will be placed in a sibling bundle corresponding to the JavaScript file.

If a resource is referenced by more than one bundle, it is promoted to the nearest public ancestor in the bundle tree so that the resource is not packaged multiple times.

3. Packing

After the bundle tree is built, each bundle is written by the packager to a file of a specific file type. The packagers know how to merge the code from each resource into the file that is ultimately loaded by the browser.

Resource Type

As resource document in the description, Parcel will be seen as the input file Resource (Asset). Resource type is seen as inherited from the base Asset subclass of the class, and implements the necessary interfaces to parse, analyze dependence, conversion and code generation.

Because Parcel processes resources in parallel in a multiprocessor core, the conversion behavior that resource types can implement is limited to those that can manipulate a single file in a single time. For those conversion behaviors that require multiple files to be manipulated, a custom Packager is required .

Resource interface

const {Asset} = require('parcel-bundler');

class MyAsset extends Asset {
 type = 'foo'; // Set the main output type

 parse(code) {
   // Parse the code into an AST tree
   return ast;
 }

 pretransform() {
   // Optional. Convert before collecting dependencies.
 }

 collectDependencies() {
   // Analytical dependence
   this.addDependency('my-dep');
 }

 transform() {
   // Optional. Convert after collecting dependencies.
 }

 generate() {
   // Generated to do the right thing. Multiple transitions can be returned if needed.
   // The result will be passed to the appropriate packagers to generate the final file bundle
   return {
     foo: 'my stuff here', // Main output
     js: 'some javascript' // This conversion can be placed in a JS file bundle if needed.
   };
 }
}

Registered Resource Type

You can use the addAssetType method to register your resource type packaging tools. It accepts a file extension and the path to the resource type module. It is a path, not an actual object, so that it can be passed to the worker process.

const Bundler = require('parcel-bundler');

let bundler = new Bundler('input.js');
bundler.addAssetType('.ext', require.resolve('./MyAsset'));

Packagers

In Parcel in a Packager plurality of Resource combined into a bundle in the finally generated. This process takes place in the main process and after all resources have been processed and the bundle tree has been created. The registration of the Packager is based on the output file type, and the resources used to generate this file type are sent to the packager to generate the resulting output file.

Packager Interface

const {Packager} = require('parcel-bundler');

class MyPackager extends Packager {
 async start() {
   // Optional, write file header content
   await this.dest.write(header);
 }

 async addAsset(asset) {
   // have to, Write resources to the makefile.
   await this.dest.write(asset.generated.foo);
 }

 async end() {
   // Optional, write the internal content of the file.
   await this.dest.end(trailer);
 }
}

Register a Packager

You can use the addPackager method to register a packager in the packaging tool. It accepts a file type and the path to the packager module for registration.

const Bundler = require('parcel-bundler');

let bundler = new Bundler('input.js');
bundler.addPackager('foo', require.resolve('./MyPackager'));

Parcel Plugin

Parcel uses a slightly different strategy than many other tools, and many common formats are included out of the box without the need to install or configure additional plugins. However, there are situations where you may want to extend the capabilities of Parcel in non-standard situations, and at that time, plugins are supported. Installed plugin based package.json dependencies are automatically detected and loaded.

When you add a new file format to Parcel, you should first consider how common it will be, and how standardized it will be. If it is generic and standard enough, the format should probably be added to the core of Parcel, not as a plug-in that users need to install. If you have other doubts, you can discuss it with GitHub .

Plugin API

The Parcel plugin is simple. They simply output several modules as a function, which is automatically called by Parcel when it is initialized. Function receives Bundleran object as input, you can do some configuration, such as the resource type registration and registration packager.

module.exports = function (bundler) {
 bundler.addAssetType('ext', require.resolve('./MyAsset'));
 bundler.addPackager('foo', require.resolve('./MyPackager'));
};

Please publish this package to npm, and the use of parcel-plugin-the prefix, so that it will automatically detect and load as mentioned later.

Using Plugins

Using plugins in Parcel is easier than ever. You do, but they are installed and saved to package.json the. Plug-in needs to parcel-plugin-be prefixed to be named. For example parcel-plugin-foo. Any package.json dependency with this prefix are listed, it is automatically loaded during initialization.

Related JavaScript Tutorials For Beginners

JavaScript Introduction Tutorials
Introduction to JavaScript
Javascript Reference and Specifications
Javascript Code editors
Javascript Developer Console
Javascript Basics
JavaScript Hello World.!
External JavaScript Files
JavaScript Code Structure
Use Strict in JavaScript
JavaScript Variables

Leave a Comment