The introduction
A few days ago, I heard a friend talking about snowpack, so I went to see what this bag is for, and checked the official website. I found it quite interesting. It claims to display code results in real time in the browser without the need for a Webpack (Parcel). Can look at the following picture first, isn’t it very attractive?
Snowpack is based on ES Modules, if you are not familiar with ES Modules, please check out my last article first.
Why snowpack
Before ESM came into being, there were various specifications for JavaScript modularization, including CommonJS, AMD, CMD, UMD, etc. The most extensive is CommonJS of Node.js. Exports import modules using module.exports and require, which is the main format provided by modules in NPM. Because browsers don’t support these modules directly, packaging tools (Webpack, Browserify, Parcel, etc.) appear.
- Have you ever run into webApps where you have to wait to see the result, and the computer goes crazy every time you save it?
- Packaging tools like WebPack are very powerful. They introduce configurations, plug-ins, and dependencies at very low cost. Creating a React application will require installing 200 MB dependencies and writing many lines of WebPack configuration.
- ESM has been in use in browsers for about 5 years and is now supported in all modern browsers (dating back to early 2018). With ESM, there is no need for packaging tools. You can build a modern, high-performance, production-ready Web application without Webpack!
- Install and run snowpack once instead of Webpack, Parcel and other miscellaneous packaging tools for a faster development environment and reduced tool complexity.
The environment to support
Since snowpack installs NPM dependencies as ES modules (ESM) by default, what is the support for ES modules?
Don’t worry, 90% of the browsers in use today support ESM syntax. Since the beginning of 2018, all modern browsers (Firefox, Chrome, Edge, Safari) support ESM.
The sample
Environment required: Node 10 +
basis
So much for convenience. So let me actually do it.
Take the React project as an example
mkdir snowpack-demo
cd snowpack-demo
npm init -y
Copy the code
Install dependencies
npm i @babel/cli @babel/core @babel/preset-react servor snowpack -D
npm i react@npm:@pika/react react-dom@npm:@pika/react-dom -S
Copy the code
// src/index.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
function App() {
return (
<div>hello world</div>
);
}
window.addEventListener("load".() = >
ReactDOM.render(<App />.document.getElementById("app")));Copy the code
<div id="app"></div>
<script type="module" src="/dist/index.js"></script>
Copy the code
npx snowpack
babel src/ --out-dir dist
npx servor --reload
Copy the code
Open http://localhost:8080
The advanced
Using CSS
Because browsers do not support importing CSS directly with JS, the following code cannot be used.
- NOT SUPPORTED OUTSIDE OF BUNDLERS
import './style.css';
Copy the code
If you want to import CSS, you need to import resources directly with the style tag.
The official recommended way to use it is
- Simple application, use restrained style
- Css-in-js is recommended for complex applications
Hence, styled- Components is used here
npm i styled-components -S
npx snowpack
Copy the code
Modified index. Js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import styled from 'styled-components';
const UI = styled.div` color: red `
function App() {
return (
<UI>
hello world
</UI>
);
}
window.addEventListener("load".() = >
ReactDOM.render(<App />.document.getElementById("app")));Copy the code
Modify the package. The json
"start": "babel src/ --out-dir dist --watch & servor --reload"
Copy the code
npm run start
Copy the code
Use pictures
- NOT SUPPORTED OUTSIDE OF BUNDLERS
import './photo.png';
Copy the code
Today, no browser supports importing images directly from JS. Instead, you will use one of the following libraries/solutions:
<img src="/img/photo.png">
Use the TypeScript
npm i @babel/preset-typescript typescript -D
Copy the code
Modify. Babelrc
{
"presets": ["@babel/preset-react"."@babel/preset-typescript"]."plugins": [
"snowpack/assets/babel-plugin.js"]}Copy the code
Change SRC /index to SRC /index.tsx and add the declaration.
import React, { useState } from "react";
import ReactDOM from "react-dom";
import styled, { ThemeProvider } from 'styled-components';
const ThemeColor = {
default: 'red'
}
interface Theme {
themeColor: typeof ThemeColor
}
const UI = ({ children }: { children? : React.ReactNode }) = > {
return (
<>
<ThemeProvider theme={ThemeColor}>{children}</ThemeProvider>
</>
);
};
const AppStyle = styled.div<Theme>((props: Theme) = > {
console.log(props);
return {
color: props.theme.default
}
})
function App() {
return (
<UI>
<AppStyle>
hello world
</AppStyle>
</UI>
);
}
window.addEventListener("load".() = >
ReactDOM.render(<App />.document.getElementById("app")));Copy the code
Modify the startup command so that Babel contains an escape from the suffix TSX.
{
"start": "babel src/ --out-dir dist --watch --extensions \".ts,.tsx,.js,.jsx\" & servor --reload"
}
Copy the code
To optimize the
By default, Snowpack installs minimal dependencies and is optimized for development. When ready for production, run Snowpack using the –optimize flag to enable some production-only optimizations:
- Minimize dependencies
- Escape low-level syntax
Tree-Shaking
(by--include
Start automatic mode)- Support old version browsing
--nomodule
If you want to build a one-page application (SPA), run Snowpack using –nomodule and pass in the application entry point. Then, create a second script tag in your application with a nomodule entry.
<! -- Ignored by legacy browsers: -->
<script type="module" src="/src/index.js"></script>
<! -- Ignored by modern browsers: -->
<script nomodule src="/web_modules/app.nomodule.js"></script>
Copy the code
Once you’ve done this, run snowpack to generate a /web_modules/app.nomodule. Js script that will automatically run on the older browser.
Cache handling
By passing addVersion
/* .babelrc */
"plugins": [["snowpack/assets/babel-plugin.js", {"addVersion": true}]]Copy the code
You can output scripts with version numbers
// src/ File Input
import Foo from 'package-name';
// lib/ Babel Output
import Foo from '/web_modules/package-name.js? V = 1.2.3 ';
Copy the code
At the end
Snowpack advantage
- Reduce the time cost of packaging, just once
snowpack
. Modified source code can be fed back to the browser in real time. - Code portability is strong, equivalent to pure writing JavaScript language.
- Modules and source code are independent of each other, somewhat like WebPack
DDL
. - For simple applications can be built quickly, for some online editing websites can use similar schemes to build.
Snowpack disadvantage
- It has a strong dependence on ES Modules. Although the packages of ES Modules are gradually increasing on NPM, extra processing is needed for all packages in the short term. For example, I want to introduce
Antd
And found a lot of dependenceCommonJS
Modules and styles do not use CSS-in-JS, which is cumbersome to introduce.
- For some
css
.images
Resource handling is not friendly, requires additional manual handling, and low-level userollup
To do it onceES Modules
Exports are too blunt, with no powerful custom plug-ins or configurations. - Too many dependent packages can cause network problems
Examples above: github.com/hua1995116/…
It is still too young for Snowpack at this stage, but youth is always full of hope and possibility.
Past wonderful
Modular series completely clears up AMD,CommonJS,CMD,UMD,ES6
Node + NAPI implements the C++ extension – LRU elimination algorithm