Loading...
Loading...
Best practices and guidelines for Parcel, the zero-configuration web application bundler
npx skill4agent add mindrally/skills parcel-bundlerproject/
├── src/
│ ├── index.html # HTML entry point
│ ├── index.js # JavaScript entry
│ ├── styles.css # Stylesheets
│ └── assets/ # Images, fonts, etc.
├── dist/ # Build output (auto-generated)
├── .parcelrc # Optional configuration
└── package.json# Development with hot reload
parcel src/index.html
# Production build
parcel build src/index.html{
"scripts": {
"dev": "parcel src/index.html",
"build": "parcel build src/index.html",
"clean": "rm -rf dist .parcel-cache"
},
"source": "src/index.html"
}<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<div id="app"></div>
<script type="module" src="./index.js"></script>
</body>
</html>parcel build src/index.js --dist-dir libparcel build src/index.html src/admin.html.js.jsx.ts.tsx.mjs.css.scss.sass.less.styl.html.htm.png.jpg.gif.svg.webp.woff.woff2.ttf.otf.eot.json.yaml.toml.xml.wasm{
"extends": "@parcel/config-default",
"transformers": {
"*.svg": ["@parcel/transformer-svg-react"]
},
"reporters": ["...", "parcel-reporter-bundle-analyzer"]
}{
"targets": {
"main": {
"source": "src/index.js",
"distDir": "dist",
"context": "browser",
"outputFormat": "esm"
}
}
}.ts.tsx{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"isolatedModules": true
}
}// Parcel handles JSX automatically
import { useState } from 'react';
function App() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}import './styles.css';import * as styles from './Button.module.css';
function Button() {
return <button className={styles.primary}>Click me</button>;
}import './styles.scss';sass.scssimport logo from './logo.png';
import data from './data.json';
// Use in JSX
<img src={logo} alt="Logo" />const imageUrl = new URL('./image.png', import.meta.url);// Automatic code splitting
const LazyComponent = React.lazy(() => import('./LazyComponent'));
// Or manual
async function loadModule() {
const module = await import('./heavy-module.js');
return module.default;
}# .env
API_URL=https://api.example.com# .env.production
API_URL=https://api.production.comconst apiUrl = process.env.API_URL;{
"targets": {
"default": {
"publicUrl": "/my-app/"
}
}
}parcel src/index.html
# Serves at http://localhost:1234parcel src/index.html --port 3000parcel src/index.html --https{
"devServer": {
"proxy": {
"/api": {
"target": "http://localhost:8080"
}
}
}
}parcel build src/index.htmlparcel build src/index.html --dist-dir build --public-url /app/parcel build src/index.html --no-source-mapsnpm install -D parcel-reporter-bundle-analyzer
# Add to .parcelrc
{
"extends": "@parcel/config-default",
"reporters": ["...", "parcel-reporter-bundle-analyzer"]
}# Clear cache
rm -rf .parcel-cache
# Or
parcel build --no-cache{
"name": "my-library",
"source": "src/index.ts",
"main": "dist/main.js",
"module": "dist/module.js",
"types": "dist/types.d.ts",
"targets": {
"main": {
"outputFormat": "commonjs"
},
"module": {
"outputFormat": "esmodule"
},
"types": {
"source": "src/index.ts"
}
}
}<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My App</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./index.tsx"></script>
</body>
</html>parcel build src/*.htmlconst worker = new Worker(new URL('./worker.js', import.meta.url), {
type: 'module'
});rm -rf .parcel-cache distparcel build --log-level verboseDEBUG=parcel:* parcel build