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.

  1. 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?
  2. 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.
  3. 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!
  4. 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

  1. Simple application, use restrained style
  2. 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:

  1. Minimize dependencies
  2. Escape low-level syntax
  3. Tree-Shaking(by--includeStart automatic mode)
  4. 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

  1. Reduce the time cost of packaging, just oncesnowpack. Modified source code can be fed back to the browser in real time.
  2. Code portability is strong, equivalent to pure writing JavaScript language.
  3. Modules and source code are independent of each other, somewhat like WebPackDDL.
  4. For simple applications can be built quickly, for some online editing websites can use similar schemes to build.

Snowpack disadvantage

  1. 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 introduceAntdAnd found a lot of dependenceCommonJSModules and styles do not use CSS-in-JS, which is cumbersome to introduce.

  1. For somecss.imagesResource handling is not friendly, requires additional manual handling, and low-level userollupTo do it onceES ModulesExports are too blunt, with no powerful custom plug-ins or configurations.
  2. 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

Focus on