🥳 welcome interested partners, do something meaningful together!
I launched a weekly translation project at github.com and fedarling.github. IO
Currently, there is still a lack of like-minded partners, which is purely personal interest. Of course, it will also help to improve English and front-end skills. Requirements: English should not be too bad, proficient in using Github, persistent, modest, and responsible for what they do.
If you want to participate, you can either click here to view it or send an issue message to the warehouse. My blog also has specific personal contact information: daodaolee.cn
Over the past year, a slew of new development tools have been launched, including but not limited to WebPack, Babel, Rollup, Parcel, Create-React-app, and more, and are friendly in terms of front-end compatibility. These new tools have different goals and features, each with different goals and features, but they all share the same goal: improving the user experience.
In fact, I’d like to evaluate each of them, outlining what they do, why we need them, and their use cases. But then I realized that comparison is always a little unfair. For example, Snowpack and Vite mostly use esbuild in the background for certain tasks. We should learn more and better about the tasks at hand so that we can choose the best ones when we need them.
Of course, there’s been a ton of articles written about these new build tools, but I recommend a few episodes from ShopTalk Show: the authors of 454-Vite, 448-WMR, and Snowpack.
Why are there so many tools?
In part, I think these tools come about because JavaScript tools are sometimes inconvenient — and this article about learning JavaScript as early as 2016 brings up some pain points.
Snowpack, Vite, and WMR are all written using native JavaScript Modules in the browser. Back in 2018, Firefox 60 enabled the ECMAScript 2015 module by default. Since then, all major browser engines have supported native JavaScript Modules. Node.js also released native JavaScript Modules in November 2019. So far, we’re still exploring more features of JavaScript Modules.
How are these different from existing tools?
Whether we use Webpack, Rollup, or Parcel as a service for our development environment, these tools package our entire code base from our source code and a node_modules folder, Run some code (like Babel, TypeScript, or PostCSS) through the build process, and then put the packaged code to run in our browsers. All of this work needs to be done, even if caching and optimization strategies are added if the code is large.
Snowpack, Vite and WMR services do not. Instead, they wait until the browser finds the import statement and makes an HTTP request to modules. Only after this request is made will the tools transform the requested module and any child nodes in the Import Module tree and then provide them to the browser. This is faster because there is less work being done in pushing services to the development environment.
Make a quick summary
First, they all support the following out-of-the-box functionality (to varying degrees) :
- Native JavaScript modules are supported
- All compile in TypeScript
- Support JSX
- Both have extendable plug-in apis
- Both have built-in services for the development environment
- CSS bundles and CSS-in-JS libraries are supported
These tools can compile TypeScript into JavaScript, even if there are type errors. If you want proper type checking, you need to install TypeScript and run TSC –noEmit on the root JavaScript file, or use an editor plug-in to monitor for type errors.
Here are the tools to analyze one by one!
esbuild
Esbuild was created by Evan Wallace, CTO of Figma. Its main feature is that it provides build steps that are 10-100 times faster (depending on their own benchmarks) than Node-based packagers. Although it does not provide dependency support similar to create-react-app packages, more and more esbuild users do these things, including but not limited to create-react-app-esbuild, Estrella, and Snowpack.
Esbuild was born late. It’s not 1.0 yet, and it’s not quite ready for production yet — but it’s not far off.
Usage scenarios
Esbuild is a new originator of the packer. This is especially true in large code bases where the speed difference between Esbuild and Node Bundlers multiplies. By the time esBuild reaches 1.0, it can be useful in large production environments and save teams a lot of time waiting for builds to complete.
Set up the
I want to start a React project in esbuild from the command line: NPM installs esbuild, React, and ReactDOM. I created a SRC /app.jsx file and a dist/index.html file. I then compiled the application into a dist/bundle.js file using the following command:
./node_modules/.bin/esbuild src/app.jsx --bundle --platform=browser --outfile=dist/bundle.js
Copy the code
When I opened index.html in the browser, the screen went blank and an error was reported: “Uncaught ReferenceError: Process is not defined”. That’s the problem with not looking carefully at the document, which requires an extra argument when building React:
--define:process.env.NODE_ENV=\"production\"
Copy the code
Alternatively, you can add an escape symbol:
--define:process.env.NODE_ENV=\\\"production\\\"
Copy the code
This definition parameter is required for any library that requires an environment variable parameter. Vue 2.0 is certainly required; Preact is not.
usage
Esbuild provides a — Serve option for development environment services. This configuration bypasses the file system and provides modules directly from memory, ensuring that browsers do not pull older versions of modules. However, it does not include real-time/hot reloading. In this case we can use the servor package to save our changes:
npm install servor --save-dev
Copy the code
We can then start using the esbuild Javascript API as the server while running esbuild’s Watch mode. Create a file named watch.js in the root directory of the project:
// watch.js
const esbuild = require("esbuild");
const servor = require("servor");
esbuild.build({
// Configure esbuild here
entryPoints: ["src/app.jsx"].outdir: "dist".define: { "process.env.NODE_ENV": '"production"' },
watch: true});async function serve(){
console.log("running server from: http://localhost:8080/");
await servor({
// Configure the server here
browser:true.root: "dist".port: 8080}); } serve();Copy the code
Now run Node Watch.js from the command line. So far, you can see our changes, but it doesn’t give us hot module replacement or quick refresh (that is, it doesn’t preserve your client state).
If you need a pre-configured version of esbuild with real-time reloads and some React defaults, check out this repository.
Supported file types
Esbuild can import CSS in JavaScript. It compiles the CSS to a directory with the same name as the main output JavaScript file. By default, it can also be bundled with CSS @import statements, although CSS Modules are not currently supported.
Now, there are more and more plug-ins for esBuild, such as the Vue SFC plug-in and the Svelte component plug-in.
It can also import images in JavaScript, convert them to urls, or copy them to an output folder. Change is not enabled by default, but you can enable either option by adding the following to the esBuild configuration:
loader: { '.png': 'dataurl' } // Converts to data url in JS bundle
loader: { '.png': 'file' } // Copies to output folder
Copy the code
Code splitting is an increasing feature and is typically output in ESM format. Also, tree-shaking is built into EsBuild by default and cannot be turned off.
The production environment
Using the “minify” and “bundle” configurations in the esbuild command does not create small bundles like Rollup/Terser. This is because esbuild sacrifices some package size optimization. But these are negligible.
conclusion
esbuild | |
---|---|
Supports multiple front-end framework template configurations | ❌ |
Support for hot update/replace development environment services | ❌ |
Streaming into | ❌ |
The production environment is preconfigured | ❌ |
Automatic PostCSS and preprocessor conversion | ❌ |
HTML conversion | ❌ |
Support a Rollup | ❌ |
The size of the | 7.34 MB |
Snowpack
Snowpack is a build tool for the creators of Skypack and Pika. It provides a great development environment service and was created with the concept of “unbundled development” in mind. To quote from the documentation: “You use a packer because you want to, not because you need to.”
By default, Snowpack’s build step does not bundle files into a single package, but instead provides unbundled esmodules that run in a browser. Esbuild is actually one of them as a dependency, but the idea is to use JavaScript modules and only bundle with esBuild when needed.
Snowpack has great documentation, including guidance on how to use it with JavaScript frameworks, and a bunch of templates. It seems Snowpack treats Svelte as a first class citizen. In fact, I first heard about Snowpack from Rich Harris’s “Future of Web Development” talk at the Svelte Summit 2020. That said, the upcoming SvelteKit framework was originally powered by Snowpack, but has since been switched to Vite.
Usage scenarios
If you prefer unbundled deployment, Snowpack is a good choice.
Second, I think Snowpack is a good encapsulation of esbuild. If you want to try esbuild, but want a development environment service and precompiled templates for the front-end framework, you can’t go wrong with Snowpack.
As it stands now, I don’t think Snowpack is the best alternative to a zero-configuration tool like create-React-app.
Set up the
Install from the command line:
mkdir snowpackproject
cd snowpackproject
npm init #fill with defaults
npm install snowpack
Copy the code
Next, add the following configuration to package.json:
// package.json
"scripts": {
"start": "snowpack dev"."build": "snowpack build"
},
Copy the code
Create another configuration file:
// Mac or Linux
touch snowpack.config.js
// Windows
new-item snowpack.config.js
Copy the code
Paste it into the configuration file:
// snowpack.config.js
module.exports = {
packageOptions: {
"source": "remote",}};Copy the code
Source: Remotely enable streaming imports. Streaming import can skip NPM and directly import CDN.
Next, create an index.html:
<! --index.html-->
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">>
<title>Snowpack streaming imports</title>
</head>
<body>
<div id="root"></div>
<! -- Note the type="module". This is important for JavaScript module imports. -->
<script type="module" src="app.js"></script>
</body>
</html>
Copy the code
Finally, we’ll add an app.jsx file:
// app.jsx
import React from 'react'
import ReactDOM from 'react-dom'
const App = () = >{
return <h1>Welcome to Snowpack streaming imports!</h1>
}
ReactDOM.render(<App />.document.getElementById('root')); 0
Copy the code
Please note that we did not install React or ReactDOM at any stage. Then we start the following Snowpack development environment services:
./node_modules/.bin/snowpack dev
Copy the code
Our program can still run!
Instead of extracting the NPM package from the node_modules folder, Snowpack extracts the NPM package from Skypack, which is a CDN that hosts the NPM registry and has been pre-optimized to work in browsers. Snowpack then provides it in the./_snowpack/ PKG URL.
usage
This is very different from the Node/ NPm-based workflow. What we’re actually seeing is a new workflow based on CDN/JavaScript modules.
However, if we run our application as-is and pack it, Snowpack throws an error. This is because it needs to know which versions of React and ReactDOM to use at build time. In this case, you can solve the problem by running the following command to automatically create snowpack.deps.json:
./node_modules/.bin/snowpack add react
./node_modules/.bin/snowpack add react-dom
Copy the code
This will not download packages from NPM, only the versions of packages used for Snowpack builds will be recorded.
Even if we don’t use streaming imports, the Snowpack development environment service bundles each dependency in node_Modules into a JavaScript file, converts these files into a native JavaScript module, and then feeds it to the browser. This means that the browser can cache these scripts and only re-request them if they change. The development environment service refreshes automatically when saved, but does not preserve the state of the client. All dependencies from nodes seem to work out of the box.
Preserving client state in React requires React-Refresh, which requires some of its own Babel dependencies, in addition to its own default configuration items. You can use the more powerful React template. The template includes react-Refresh, Prettier, Chai, and React test libraries, with a total of 80 MB of Node dependencies:
npx create-snowpack-app my-react-project --template @snowpack/app-template-react
Copy the code
Supported file types
JSX is supported, but again, only.jsx files are supported by default. Snowpack automatically detects whether React or Preact is used and decides accordingly which render function to use for the JSX transformation. However, if we want to further customize JSX, we need to introduce Babel through their plug-in. There is also a Snowpack plug-in available for Vue single-file components and, of course, for Svelte components. Snowpack also compiles TypeScript, but we also need TypeScript plug-ins for type checking.
CSS can be imported into JavaScript and put into the document at run time. It also supports the out-of-the-box experience of CSS modules with.module. CSS extensions. The imported JSON file is converted to a JavaScript Module and the object is exported by default. Snowpack copies images to folders in the production environment. In keeping with its unbundled philosophy, Snowpack does not include images as urls in bundles.
The production environment
The default snowpack build command copies the source file structure into the output folder. For files compiled to JavaScript (such as TypeScript, JSX, JSON,.vue,.svelte), it converts each individual file into a JavaScript Module.
As you can see, this is not very production-friendly, as it can cause a lot of requests if the source code is split into many files.
However, Snowpack uses esbuild as a dependency. We can enable esbuild by adding an “optimize” parameter to the Snowpack configuration to bundle, compress, and compile code:
// snowpack.config.js
module.exports = {
optimize: {
bundle: true.minify: true.target: 'es2018',}};Copy the code
This will use the optimization features provided by EsBuild, and we will have the same build as we had with EsBuild before. Since esbuild has not yet reached 1.0, Snowpack recommends using the WebPack or Rollup plug-in for production builds, both of which require configuration.
conclusion
Snowpack currently has fully featured development environment services, detailed documentation, and easy-to-get started templates.
Snowpack | |
---|---|
Supports multiple front-end framework template configurations | ✅ |
Support for hot update/replace development environment services | ✅ |
Streaming into | ✅ |
The production environment is preconfigured | ❌ |
Automatic PostCSS and preprocessor conversion | ❌ |
HTML conversion | ❌ |
Support a Rollup | ✅ |
The size of the | 16 MB |
Vite
Vite was developed by Evan You. While EsBuild focuses on build steps, Snowpack focuses on development environment services, Vite includes both: full development environment services and optimized build commands using Rollup.
Usage scenarios
If you’re looking for a create-React-app or Vue CLI competitor, Vite is the closest one because of its full functionality. Lightning-fast development environment services and zero-configuration production builds mean you can use them without any configuration. Vite is friendly for any large single-page application.
If you want a server-side rendering framework with zero configuration, you’re better off using webPack frameworks like Nuxt.js and next.js until the Vite server-side rendering has been refined.
Set up the
Vite has more specific defaults than esbuild and Snowpack. Its documentation is also friendly, and Vite can be used with any front-end framework, even providing a list of templates to help you get started.
usage
Vite’s development environment services are very powerful. Vite uses esbuild to pre-bundle all of the project’s dependencies into a single native JavaScript module, which it then serves with cached HTTP headers. This means that no more time is wasted supplying or requesting imported dependencies after the first compile. Vite also provides clear error messages, printing the exact code block and line number for troubleshooting.
Vite’s React and Vue templates both introduce plugins that support hot module replacement. Vue template plug-ins are provided for single-file components and JSX plug-ins. The React template introduces the React – Refresh plugin. Either way, both provide you with hot module replacement and client-side state preservation. Of course, they have more dependencies, including the Babel package and so on, but Babel is not really needed to use JSX in Vite. By default, JSX works the same as esbuild — it converts to react.createElement.
Vite does not support streaming imports like Snowpack and WMR, so NPM installation dependencies can only be used as usual.
Vite is experimenting with server-side rendering, selecting frames and generating static HTML sent directly to the client. Evan You already has a project in the works called VitePress, which is an alternative to VuePress and also has the advantages of using Vite. And Sveltekit also adds Vite to its list of dependencies. It seems that the split of CSS code may have something to do with Sveltekit switching to Vite.
Supported file types
For CSS, Vite supports bundled CSS imports as well as CSS modules. We can also create a postcss.config.js file using the NPM install PostCSS plug-in, and Vite will automatically apply these transformations to CSS.
Vite also supports CSS preprocessors – simply NPM installs the preprocessor and renames the file to the correct extension (e.g..filename.scss).
Image imports default to public urls, but we can also use? The RAW argument loads them into the package as strings.
JSON files can be imported and converted into esModules that export individual objects. You can also provide a named import, and Vite will look for the import in the root field of the JSON file and treeshake the rest.
The production environment
Vite uses Rollup for pre-configured production builds with a number of optimizations. It specifically provides a zero configuration build, which should be sufficient for most use cases. This build capability also carries the functionality expected of Rollup: bundling, compression, and tree shaking. There are other things as well, such as code splitting, dynamic imports, and asynchronous chunk loading, which is interesting because if we request a JavaScript module that imports another module, they will be built asynchronously.
conclusion
Vite’s features make it a strong contender for current build tools, and it does a lot of work in terms of a truly seamless development experience and out of the box.
Vite | |
---|---|
Supports multiple front-end framework template configurations | ✅ |
Support for hot update/replace development environment services | ✅ |
Streaming into | ❌ |
The production environment is preconfigured | ✅ |
Automatic PostCSS and preprocessor conversion | ✅ |
HTML conversion | ❌ |
Support a Rollup | ✅ |
The size of the | 17.1 MB |
wmr
WMR, like Vite, is another unique build tool that provides development environment services and build steps. It was built by Jason Miller, the creator of Preact, so it’s definitely a comfortable choice for Preact developers. Jason Miller explained the thinking behind WMR during a guest appearance on the JS Party podcast.
You may be wondering what WMR stands for? It could be “Web Modules Runtime” or “Wet Module Replacement”, who knows (similar to NPM).
WMR is small, only 2.6 MB, and does not come with any NPM dependencies. Nevertheless, it contains a number of great features, including hot module replacement development environment services and optimized production builds.
Usage scenarios
If I want to create a project using Preact as soon as possible, I use WMR. No configuration required and the download takes seconds. It feels like using a pressurized static file server. With TypeScript, optimized build steps, and static HTML rendering, WMR provides everything you need to deliver small to medium sized applications. If you don’t use Preact, React, or Vanilla JavaScript, WMR may not be for you. The Preact team hasn’t provided templates for other frameworks, and the documentation isn’t as detailed as the other tools we’ve looked at.
Set up the
If you use Preact, no configuration is required other than a quick NPM installation. To use React in WMR, change the HTM /preact name to HTM/React, and configure es-react in package.json:
"alias": {
"htm/preact": "htm/react"."react": "es-react"
},
Copy the code
Then add the import to the component:
// ReactDOM only needed on root render
import { React, ReactDOM,} from 'es-react';
Copy the code
So instead of using the normal React package, we actually imported React from es-React. This is because WMR relies on packages that are compatible with native JavaScript modules. By default, React uses UMD modules instead of native modules. Es-react is a Web platform-compatible package derived from React.
Alternatively, you can use the Skypack import, which is preloaded in the browser:
import React from 'https://cdn.skypack.dev/react';
import ReactDOM from 'https://cdn.skypack.dev/react-dom';
Copy the code
WMR has a number of plug-in apis, such as a Rollup plug-in API that supports build steps. There are also some examples of WMR, such as a plug-in for compressed HTML and a file system-based routing plug-in.
WMR supports different frameworks, but does not have any pre-built templates.
usage
From the command line, run the following command:
npm init wmr your-project-name
Copy the code
Alternatively, you can build it manually:
npm init -y
npm install wmr
mkdir public
touch public/index.html
touch public/index.js
Copy the code
Then add a script import to index.html (again make sure to use type=”module”) :
<script type="module" src="./index.js"></script>
Copy the code
Now you can write Hello World to your index.js file:
import { render } from 'preact';
render(<h1>Hello World!</h1>.document.body);
Copy the code
Finally, start the service:
node_modules/.bin/wmr
Copy the code
We now have a complete hot module replacement development environment service that responds immediately to any changes to our source code.
WMR uses a tool called HTM when converting JSX. Suppose we were writing a counter in WMR using Preact and made an error:
import { render } from 'preact';
import { useState } from 'preact/hooks';
function App() {
const [count,setCount] = useState(0)
return <>
<button onClick={()= >{setCount(cout+5)}}>Click to add 5 to count</button> // HIGHLIGHT
<p>count: {count}</p>
</>
}
render(<App />.document.body);
Copy the code
Count is misspelled in the onClick handler, so an error is reported. Normally, we would have to rely on our tools and source maps to gather information about where the error is, but WMR takes a different approach. If you use HTM, you’ll probably be close to native JSX writing, so a common place to write React or Preact code would look like this:
<MyComponent>I am JSX. I am not actually valid Javascript</MyComponent>
Copy the code
HTM looks more like this:
html`<${MyComponent}>I am about as close as it gets to JSX as you can get while being able to run in the browser</MyComponent>`
Copy the code
Now, if we open the “Sources” panel of the F12 console, we should see the following image:
This way, we can properly investigate errors in the browser without using source maps.
WMR supports streaming imports by default, so raw imports (imports without relative/absolute paths) will be pulled from the NPM registry. This process is a bit complicated, examining all the source code in the NPM package, removing all the tests and metadata, and converting it to a single native JavaScript import. Similar to Snowpack, complex applications can be built without installing anything using NPM. In fact, WMR is the first tool to support this idea.
Supported file types
WMR supports the ability to import CSS files in JavaScript, as well as CSS Modules.
There is no built-in support for Vue single-file components or Svelte components. However, the WMR build steps can be used in conjunction with the Rollup plug-in, and the development environment service can be configured with Polka/ Express middleware, so you can use these to translate imports into Vue and Svelte components.
Without the plugin, we can’t import images into JavaScript as urls in WMR. So, if we had a picture of a puppy, we might include it in the Preact component as follows:
function Dog() {
return <img src={new URL('./dog.jpg', import.meta.url)} alt="dog hanging out"></img>
}
Copy the code
Once the build starts, the image is copied and reachable from within the file. Images in the development environment service have hot module replacement, so changes to the image are immediately reflected in the browser.
One other note about file support: JSON can be imported and converted into JavaScript objects. But to actually build the application, we need the Rollup JSON plug-in.
The production environment
WMR has complete production build steps, including bundling, compression, and tree shaking, without any additional dependencies. Another way to configure WMR is to render the application as static HTML and hydrates it on the browser using preact-ISO. This means that WMR can be used as a meta-framework for Preact, similar to Next-js.
conclusion
wmr | |
---|---|
Supports multiple front-end framework template configurations | ✅ |
Support for hot update/replace development environment services | ✅ |
Streaming into | ✅ |
The production environment is preconfigured | ✅ |
Automatic PostCSS and preprocessor conversion | ✅ |
HTML conversion | ❌ |
Support a Rollup | ✅ |
The size of the | 17.1 MB |
Functional comparison
Introduction to the
tool | The characteristics of |
---|---|
esbuild | Large code base, not ready for production. |
Snowpack | Small applications that do not need to be bundled are also suitable for applications rendered on the server. |
Vite | Can generate a single page application, instead of Vue CLI/ create-react-app, happy water for Vue players. |
wmr | Suitable for small to medium sized applications, can be used for single page or server rendering applications, Preact players happy water. |
use
esbuild | Snowpack | Vite | wmr | |
---|---|---|---|---|
Support for multiple front-end framework templates | ❌ | ✅ | ✅ | ❌ |
Install the default disk usage | 7.34 MB | 16 MB | 17.1 MB | 2.57 MB |
Zero configuration build packaging | ❌ | ❌ | ✅ | ✅ |
Zero configuration hot update development environment service | ❌ | ✅ | ✅ | ✅ |
Node package environment variable handling | ❌ | ✅ | ✅ | ✅ |
Development Environment Services
esbuild | Snowpack | Vite | wmr | |
---|---|---|---|---|
Hot update | ❌ | ✅ | ✅ | ✅ |
CSS hot replacement | ❌ | ✅ | ✅ | ✅ |
NPM relies on pre-bundling | ❌ | ✅ | ✅ | ❌ |
The browser displays an error message | ❌ | ✅ | ✅ | ❌ |
HTM conversion | ❌ | ❌ | ❌ | ✅ |
The production building
esbuild | Snowpack | Vite | wmr | |
---|---|---|---|---|
Relying on the Go | ✅ | ✅ when building using esBuild | ❌ | ❌ |
Preconfigured build | ❌ | ❌ | ✅ | ✅ |
Asynchronous chunk loading | ❌ | ❌ | ✅ | ✅ |
Rollup plug-in is supported | ❌ | ✅ | ✅ | ✅ |
Other features
esbuild | Snowpack | Vite | wmr | |
---|---|---|---|---|
Current input | ❌ | ✅ | ❌ | ✅ |
Server side rendering | ❌ | ❌ | ✅ (Experiment) | ✅ |
CSS Modules | ❌ | ✅ | ✅ | ✅ |
Automatic PostCSS and preprocessor conversion | ❌ | ❌ | ✅ | ❌ |
A link to the
Comparing the New Generation of Build Tools
Translation plan