Snowpack Cheatsheet¶
- Das schnellere Frontend Build Tool
Snowpack ist ein blitzschnelles Frontend-Building-Tool, entworfen für das moderne Web. Es nutzt JavaScripts natives Modulsystem (ESM), um unnötige Arbeit zu vermeiden und schnell zu bleiben, egal wie groß Ihr Projekt wächst. < p>
Inhaltsverzeichnis¶
- [Installation](#installation
- (#getting-started)
- [Konfiguration](#configuration_
- (#development-server_)
- [Build Process](LINK_4__
- (Plugins)(LINK_5_)
- (#package-management_)
- (#hot-module-replacement_)
- [TypeScript Support](#typescript-support_
- [CSS und Styling](LINK_9_
- (#asset-handling_)
- Umweltvariablen
- [Optimierung](LINK_12__
- [Bestellung](LINK_13__
- [Migration](LINK_14__
- (#troubleshooting)
- Beste Praktiken
Installation¶
Globale Installation¶
# Install Snowpack globally
npm install -g snowpack
# Check version
snowpack --version
```_
### Lokale Installation (empfohlen)
```bash
# Initialize npm project
npm init -y
# Install Snowpack locally
npm install --save-dev snowpack
# Or with Yarn
yarn add --dev snowpack
```_
### Snowpack App erstellen
```bash
# Create new app with template
npx create-snowpack-app my-app --template @snowpack/app-template-react
# Available templates
npx create-snowpack-app my-app --template @snowpack/app-template-vanilla
npx create-snowpack-app my-app --template @snowpack/app-template-react
npx create-snowpack-app my-app --template @snowpack/app-template-vue
npx create-snowpack-app my-app --template @snowpack/app-template-svelte
npx create-snowpack-app my-app --template @snowpack/app-template-preact
npx create-snowpack-app my-app --template @snowpack/app-template-lit-element
```_
### Paket.json Scripts
```json
{
"scripts": {
"start": "snowpack dev",
"build": "snowpack build",
"test": "web-test-runner \"src/**/*.test.js\"",
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"",
"lint": "prettier --check \"src/**/*.{js,jsx,ts,tsx}\""
}
}
```_
## Erste Schritte
### Struktur des Projekts
```bash
my-snowpack-app/
├── public/
│ ├── index.html
│ └── favicon.ico
├── src/
│ ├── index.js
│ ├── index.css
│ └── logo.svg
├── snowpack.config.js
└── package.json
```_
### Grundlegende HTML Eingangsstelle
```html
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Web site created using Snowpack" />
<title>Snowpack App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.js"></script>
</body>
</html>
```_
### Grundlegendes JavaScript Eintragung
```javascript
// src/index.js
import './index.css';
console.log('Hello Snowpack!');
// Hot Module Replacement API
if (import.meta.hot) {
import.meta.hot.accept();
}
```_
### Basis CSS
```css
/* src/index.css */
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
```_
### Entwicklung
```bash
# Start development server
npm start
# Or directly with Snowpack
npx snowpack dev
# Custom port
npx snowpack dev --port 3000
# Open browser automatically
npx snowpack dev --open
```_
## Konfiguration
### Grundkonfiguration
```javascript
// snowpack.config.js
module.exports = {
mount: {
public: { url: '/', static: true },
src: { url: '/dist' },
},
plugins: [
'@snowpack/plugin-react-refresh',
'@snowpack/plugin-dotenv',
],
routes: [
/* Enable an SPA Fallback in development: */
{ match: 'routes', src: '.*', dest: '/index.html' },
],
optimize: {
/* Example: Bundle your final build: */
// "bundle": true,
},
packageOptions: {
/* ... */
},
devOptions: {
/* ... */
},
buildOptions: {
/* ... */
},
};
```_
### Erweiterte Konfiguration
```javascript
// snowpack.config.js
module.exports = {
// Mount directories
mount: {
public: { url: '/', static: true },
src: { url: '/dist' },
'src/components': { url: '/components' },
'src/assets': { url: '/assets', static: true },
},
// Plugins
plugins: [
'@snowpack/plugin-react-refresh',
'@snowpack/plugin-dotenv',
'@snowpack/plugin-typescript',
'@snowpack/plugin-sass',
'@snowpack/plugin-postcss',
[
'@snowpack/plugin-webpack',
{
extendConfig: (config) => {
config.plugins.push(/* ... */);
return config;
},
},
],
],
// Routes
routes: [
{ match: 'routes', src: '.*', dest: '/index.html' },
{ match: 'routes', src: '/api/.*', dest: '/api/index.js' },
],
// Optimization
optimize: {
bundle: true,
minify: true,
target: 'es2018',
},
// Package options
packageOptions: {
source: 'local',
external: ['fs', 'path'],
env: {
NODE_ENV: true,
},
rollup: {
plugins: [/* ... */],
},
},
// Development options
devOptions: {
port: 8080,
open: 'default',
openUrl: 'http://localhost:8080',
hmr: true,
secure: false,
hostname: 'localhost',
},
// Build options
buildOptions: {
out: 'build',
baseUrl: '/',
clean: true,
sourcemap: true,
metaUrlPath: 'snowpack',
},
// Aliases
alias: {
'@': './src',
'@components': './src/components',
'@utils': './src/utils',
},
};
```_
### TypScript Konfiguration
```javascript
// snowpack.config.js
module.exports = {
mount: {
public: { url: '/', static: true },
src: { url: '/dist' },
},
plugins: [
'@snowpack/plugin-typescript',
'@snowpack/plugin-react-refresh',
],
packageOptions: {
types: true,
},
};
```_
```json
// tsconfig.json
{
"compilerOptions": {
"target": "es2018",
"lib": [
"dom",
"dom.iterable",
"es6"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": "./",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"]
}
},
"include": [
"src"
]
}
```_
## Entwicklungsserver
### Basis-Entwicklungsserver
```bash
# Start development server
snowpack dev
# Custom configuration
snowpack dev --config snowpack.dev.config.js
# Verbose output
snowpack dev --verbose
# Reload on file changes
snowpack dev --reload
```_
### Serveroptionen entwickeln
```javascript
// snowpack.config.js
module.exports = {
devOptions: {
// Port number
port: 8080,
// Hostname
hostname: 'localhost',
// Open browser
open: 'default', // 'default', 'none', or browser name
openUrl: 'http://localhost:8080',
// Hot Module Replacement
hmr: true,
hmrDelay: 0,
hmrPort: undefined,
hmrErrorOverlay: true,
// HTTPS
secure: false,
// Output
output: 'stream', // 'stream' or 'dashboard'
// Fallback
fallback: 'index.html',
},
};
```_
### Proxy Konfiguration
```javascript
// snowpack.config.js
module.exports = {
devOptions: {
port: 3000,
},
routes: [
{
src: '/api/.*',
dest: (req, res) => {
// Proxy to backend API
return proxy('http://localhost:8000', {
changeOrigin: true,
})(req, res);
},
},
],
};
```_
### Benutzerdefinierter Server
```javascript
// server.js
const { startServer } = require('snowpack');
async function start() {
const server = await startServer({
config: {
devOptions: {
port: 3000,
},
},
lockfile: null,
});
console.log(`Server started on port ${server.port}`);
}
start();
```_
## Prozess
### Basic Build
```bash
# Build for production
snowpack build
# Build with custom config
snowpack build --config snowpack.prod.config.js
# Clean build
snowpack build --clean
# Verbose build
snowpack build --verbose
```_
### Konfiguration erstellen
```javascript
// snowpack.config.js
module.exports = {
buildOptions: {
// Output directory
out: 'build',
// Base URL
baseUrl: '/',
// Clean output directory
clean: true,
// Source maps
sourcemap: true,
// Meta URL path
metaUrlPath: 'snowpack',
// Watch mode
watch: false,
},
};
```_
### Produktionsoptimierung
```javascript
// snowpack.config.js
module.exports = {
optimize: {
// Bundle files
bundle: true,
// Minify code
minify: true,
// Target environment
target: 'es2018',
// Tree shaking
treeshake: true,
// Splitting
splitting: true,
// Manifest
manifest: true,
},
buildOptions: {
sourcemap: false, // Disable source maps in production
},
};
```_
### Benutzerdefinierte erstellen Skript
```javascript
// build.js
const { build } = require('snowpack');
async function buildApp() {
const result = await build({
config: {
mount: {
public: { url: '/', static: true },
src: { url: '/dist' },
},
optimize: {
bundle: true,
minify: true,
},
},
});
console.log('Build completed!');
console.log('Result:', result);
}
buildApp().catch(console.error);
```_
## Plugins
### Grundlegende Plugins
```bash
# Install common plugins
npm install --save-dev @snowpack/plugin-react-refresh
npm install --save-dev @snowpack/plugin-typescript
npm install --save-dev @snowpack/plugin-sass
npm install --save-dev @snowpack/plugin-postcss
npm install --save-dev @snowpack/plugin-dotenv
npm install --save-dev @snowpack/plugin-webpack
```_
### React Plugin
```javascript
// snowpack.config.js
module.exports = {
plugins: [
'@snowpack/plugin-react-refresh',
],
};
```_
```jsx
// src/App.jsx
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div className="App">
<header className="App-header">
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</header>
</div>
);
}
export default App;
```_
### TypScript Plugin
```javascript
// snowpack.config.js
module.exports = {
plugins: [
'@snowpack/plugin-typescript',
],
};
```_
### Sass Plugin
```javascript
// snowpack.config.js
module.exports = {
plugins: [
'@snowpack/plugin-sass',
],
};
```_
```scss
// src/styles.scss
$primary-color: #007bff;
$secondary-color: #6c757d;
.button {
background-color: $primary-color;
color: white;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
&:hover {
background-color: darken($primary-color, 10%);
}
}
```_
### PostCSS Plugins
```javascript
// snowpack.config.js
module.exports = {
plugins: [
'@snowpack/plugin-postcss',
],
};
```_
```javascript
// postcss.config.js
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano')({
preset: 'default',
}),
],
};
```_
### Webpack Plugin
```javascript
// snowpack.config.js
module.exports = {
plugins: [
[
'@snowpack/plugin-webpack',
{
extendConfig: (config) => {
config.resolve.alias = {
'@': path.resolve(__dirname, 'src'),
};
return config;
},
},
],
],
optimize: {
bundle: true,
minify: true,
},
};
```_
### Benutzerdefiniertes Plugin
```javascript
// plugins/custom-plugin.js
module.exports = function (snowpackConfig, pluginOptions) {
return {
name: 'custom-plugin',
resolve: {
input: ['.custom'],
output: ['.js'],
},
async load({ filePath }) {
const contents = await fs.readFile(filePath, 'utf8');
// Transform the file
const result = transformCustomFile(contents);
return {
'.js': result,
};
},
};
};
// snowpack.config.js
module.exports = {
plugins: [
'./plugins/custom-plugin.js',
],
};
```_
## Paketmanagement
### Installation von Paketen
```bash
# Install packages normally
npm install lodash
npm install react react-dom
# Snowpack will automatically handle ESM conversion
```_
### Paketkonfiguration
```javascript
// snowpack.config.js
module.exports = {
packageOptions: {
// Package source
source: 'local', // 'local', 'remote', or 'remote-next'
// External packages
external: ['fs', 'path', 'crypto'],
// Environment variables
env: {
NODE_ENV: true,
API_URL: true,
},
// Package transformations
knownEntrypoints: [
'react/jsx-runtime',
'react/jsx-dev-runtime',
],
// Rollup options for dependencies
rollup: {
plugins: [
// Custom rollup plugins for dependencies
],
dedupe: ['react', 'react-dom'],
},
},
};
```_
### ESM Paket Handling
```javascript
// Snowpack automatically converts CommonJS to ESM
import _ from 'lodash'; // Works even though lodash is CommonJS
import React from 'react';
import { render } from 'react-dom';
// Dynamic imports
const dynamicModule = await import('./dynamic-module.js');
```_
### Paket Alias
```javascript
// snowpack.config.js
module.exports = {
alias: {
// Path aliases
'@': './src',
'@components': './src/components',
'@utils': './src/utils',
// Package aliases
'react': 'preact/compat',
'react-dom': 'preact/compat',
},
};
```_
## Hot Modul Ersatz
### Basis HMR
```javascript
// src/index.js
import './App.js';
// Accept HMR updates
if (import.meta.hot) {
import.meta.hot.accept();
}
```_
### Komponenten HMR
```javascript
// src/App.js
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return (
<div>
<h1>Count: {count}</h1>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
export default App;
// HMR for React components (handled by plugin)
if (import.meta.hot) {
import.meta.hot.accept();
}
```_
### HMR API
```javascript
// Advanced HMR usage
if (import.meta.hot) {
// Accept updates to this module
import.meta.hot.accept();
// Accept updates to dependencies
import.meta.hot.accept('./dependency.js', (newModule) => {
// Handle the updated dependency
console.log('Dependency updated:', newModule);
});
// Dispose callback
import.meta.hot.dispose((data) => {
// Cleanup before module is replaced
data.someState = getCurrentState();
});
// Invalidate and force full reload
import.meta.hot.invalidate();
}
```_
### CSS HMR
```css
/* src/styles.css */
.app {
background-color: #f0f0f0;
padding: 20px;
}
/* Changes to CSS are automatically hot-reloaded */
```_
```javascript
// src/index.js
import './styles.css';
// CSS changes are automatically handled by Snowpack
```_
## TypScript Support
### Haupttyp Setup
```bash
# Install TypeScript
npm install --save-dev typescript @snowpack/plugin-typescript
# Create tsconfig.json
npx tsc --init
```_
```javascript
// snowpack.config.js
module.exports = {
plugins: [
'@snowpack/plugin-typescript',
],
};
```_
### TypScript Konfiguration
```json
// tsconfig.json
{
"compilerOptions": {
"target": "es2018",
"lib": ["dom", "dom.iterable", "es6"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}
```_
### TypeScript mit React
```tsx
// src/App.tsx
import React, { useState } from 'react';
interface Props {
title: string;
}
const App: React.FC<Props> = ({ title }) => {
const [count, setCount] = useState<number>(0);
const handleIncrement = (): void => {
setCount(prev => prev + 1);
};
return (
<div>
<h1>{title}</h1>
<p>Count: {count}</p>
<button onClick={handleIncrement}>
Increment
</button>
</div>
);
};
export default App;
```_
### Art Definitionen
```typescript
// src/types/index.ts
export interface User {
id: number;
name: string;
email: string;
}
export interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
export type Theme = 'light' | 'dark';
```_
## CSS und Styling
### CSS Module
```javascript
// snowpack.config.js
module.exports = {
plugins: [
[
'@snowpack/plugin-postcss',
{
config: {
plugins: [
require('postcss-modules')({
generateScopedName: '[name]__[local]___[hash:base64:5]',
}),
],
},
},
],
],
};
```_
```css
/* src/Button.module.css */
.button {
background-color: #007bff;
color: white;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
cursor: pointer;
}
.button:hover {
background-color: #0056b3;
}
```_
```javascript
// src/Button.js
import styles from './Button.module.css';
function Button({ children, onClick }) {
return (
<button className={styles.button} onClick={onClick}>
{children}
</button>
);
}
export default Button;
```_
### Sass/SCSS Unterstützung
```bash
# Install Sass plugin
npm install --save-dev @snowpack/plugin-sass
```_
```javascript
// snowpack.config.js
module.exports = {
plugins: [
'@snowpack/plugin-sass',
],
};
```_
```scss
// src/styles.scss
$primary-color: #007bff;
$font-size-base: 1rem;
@mixin button-style($bg-color) {
background-color: $bg-color;
color: white;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
font-size: $font-size-base;
&:hover {
background-color: darken($bg-color, 10%);
}
}
.primary-button {
@include button-style($primary-color);
}
```_
### PostCSS Konfiguration
```javascript
// postcss.config.js
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-nested'),
require('autoprefixer'),
require('cssnano')({
preset: 'default',
}),
],
};
```_
```css
/* src/styles.css */
@import 'normalize.css';
:root {
--primary-color: #007bff;
--secondary-color: #6c757d;
}
.button {
background-color: var(--primary-color);
color: white;
padding: 0.5rem 1rem;
border: none;
border-radius: 0.25rem;
&:hover {
background-color: color-mod(var(--primary-color) shade(10%));
}
}
```_
## Asset Handling
### Statische Vermögenswerte
```javascript
// snowpack.config.js
module.exports = {
mount: {
public: { url: '/', static: true },
'src/assets': { url: '/assets', static: true },
},
};
```_
### Bildimporte
```javascript
// src/App.js
import logoUrl from './assets/logo.png';
import iconUrl from './assets/icon.svg';
function App() {
return (
<div>
<img src={logoUrl} alt="Logo" />
<img src={iconUrl} alt="Icon" />
</div>
);
}
```_
### Dynamische Importe
```javascript
// Dynamic asset loading
async function loadImage(imageName) {
const imageModule = await import(`./assets/${imageName}.png`);
return imageModule.default;
}
// Usage
const logoUrl = await loadImage('logo');
document.getElementById('logo').src = logoUrl;
```_
### Asset Processing
```javascript
// snowpack.config.js
module.exports = {
plugins: [
[
'@snowpack/plugin-webpack',
{
extendConfig: (config) => {
config.module.rules.push({
test: /\.(png|jpe?g|gif|svg)$/i,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images',
},
},
],
});
return config;
},
},
],
],
};
```_
## Umweltvariablen
### Basic Environment Varianten
```bash
# .env
SNOWPACK_PUBLIC_API_URL=https://api.example.com
SNOWPACK_PUBLIC_APP_NAME=My App
PRIVATE_KEY=secret123
```_
```javascript
// src/config.js
export const config = {
apiUrl: import.meta.env.SNOWPACK_PUBLIC_API_URL,
appName: import.meta.env.SNOWPACK_PUBLIC_APP_NAME,
// Private variables are not available in browser
};
```_
### Umwelt Plugin
```javascript
// snowpack.config.js
module.exports = {
plugins: [
'@snowpack/plugin-dotenv',
],
};
Kundenspezifische Umweltvariablen¶
javascript
// snowpack.config.js
module.exports = {
packageOptions: {
env: {
NODE_ENV: true,
API_URL: true,
VERSION: process.env.npm_package_version,
},
},
};_
javascript
// src/app.js
console.log('Environment:', import.meta.env.NODE_ENV);
console.log('API URL:', import.meta.env.API_URL);
console.log('Version:', import.meta.env.VERSION);_
Optimierung¶
Bündeloptimierung¶
javascript
// snowpack.config.js
module.exports = {
optimize: {
bundle: true,
minify: true,
target: 'es2018',
treeshake: true,
splitting: true,
manifest: true,
},
};_
Webpack Integration¶
javascript
// snowpack.config.js
module.exports = {
plugins: [
[
'@snowpack/plugin-webpack',
{
extendConfig: (config) => {
config.optimization = {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
};
return config;
},
},
],
],
optimize: {
bundle: true,
minify: true,
},
};_
Leistungsoptimierung¶
```javascript // src/utils/lazy.js export const lazyLoad = (importFunc) => { return React.lazy(importFunc); };
// src/App.js import React, { Suspense } from 'react'; import { lazyLoad } from './utils/lazy';
const LazyComponent = lazyLoad(() => import('./components/HeavyComponent'));
function App() { return (