Saltar a contenido

Parcel Cheatsheet

▪h1 - La herramienta de construcción de configuración cero "Clase de inscripción" Parcel es un paquete de aplicaciones web, diferenciado por su experiencia de desarrollador. Ofrece un rendimiento rápido brillante utilizando procesamiento multicore, y requiere configuración cero. ▪/p] ■/div titulada

########################################################################################################################################################################################################################################################## Copiar todos los comandos
########################################################################################################################################################################################################################################################## Generar PDF seleccionado/button

■/div titulada ■/div titulada

Cuadro de contenidos

Instalación

Instalación global

# Install Parcel globally
npm install -g parcel

# Or with Yarn
yarn global add parcel

# Check version
parcel --version

Instalación local (recomendada)

# Initialize npm project
npm init -y

# Install Parcel as dev dependency
npm install --save-dev parcel

# Or with Yarn
yarn add --dev parcel

Paquete.json Scripts

{
  "scripts": {
    "start": "parcel src/index.html",
    "dev": "parcel src/index.html --open",
    "build": "parcel build src/index.html",
    "clean": "rm -rf dist .parcel-cache"
  }
}

Comienzo

HTML básico Punto de entrada

<!-- src/index.html -->
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>My Parcel App</title>
</head>
<body>
  <div id="app"></div>
  <script type="module" src="./index.js"></script>
</body>
</html>

JavaScript básico Entrada

// src/index.js
import './styles.css';

console.log('Hello from Parcel!');

// Import and use a module
import { greet } from './utils';
greet('World');

Basic CSS

/* src/styles.css */
body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 20px;
  background-color: #f0f0f0;
}

.container {
  max-width: 800px;
  margin: 0 auto;
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

Run Development Server

# Start development server
npm start

# Or with specific port
parcel src/index.html --port 3000

# Open browser automatically
parcel src/index.html --open

Estructura del proyecto

Proyecto Parcel Típico

my-parcel-app/
├── src/
   ├── index.html
   ├── index.js
   ├── styles.css
   ├── components/
      ├── Header.js
      └── Footer.js
   ├── assets/
      ├── images/
      └── fonts/
   └── utils/
       └── helpers.js
├── dist/           # Build output
├── .parcel-cache/  # Parcel cache
├── package.json
└── .gitignore

Múltiples puntos de entrada

{
  "scripts": {
    "start": "parcel src/*.html",
    "build": "parcel build src/*.html"
  }
}

Estructura del proyecto de biblioteca

my-library/
├── src/
   ├── index.js
   ├── components/
   └── utils/
├── package.json
└── .parcelrc

Development Server

Basic Development Server

# Start dev server
parcel src/index.html

# Custom port
parcel src/index.html --port 8080

# Custom host
parcel src/index.html --host 0.0.0.0

# HTTPS
parcel src/index.html --https

# Open browser
parcel src/index.html --open

Opciones de desarrollo del servidor

# Disable HMR
parcel src/index.html --no-hmr

# Disable source maps
parcel src/index.html --no-source-maps

# Custom dist directory
parcel src/index.html --dist-dir build

# Watch additional files
parcel src/index.html --watch-dir src/data

Configuración Proxy

// package.json
{
  "scripts": {
    "start": "parcel src/index.html --port 3000"
  },
  "@parcel/resolver-default": {
    "packageExports": true
  }
}

Construcción para la producción

Producción básica

# Build for production
parcel build src/index.html

# Build with custom output directory
parcel build src/index.html --dist-dir build

# Build without source maps
parcel build src/index.html --no-source-maps

# Build without optimization
parcel build src/index.html --no-optimize

Configuración de construcción

{
  "scripts": {
    "build": "parcel build src/index.html",
    "build:analyze": "parcel build src/index.html --reporter @parcel/reporter-bundle-analyzer",
    "build:stats": "parcel build src/index.html --reporter @parcel/reporter-bundle-buddy"
  }
}

Optimizaciones de producción

# Enable scope hoisting
parcel build src/index.html --experimental-scope-hoisting

# Custom public URL
parcel build src/index.html --public-url /my-app/

# Detailed bundle report
parcel build src/index.html --detailed-report

Tipos de activos

JavaScript y TipoScript

// ES6 modules
import { helper } from './utils/helper.js';

// CommonJS
const lodash = require('lodash');

// Dynamic imports
const module = await import('./dynamic-module.js');

// TypeScript
import { Component } from './Component.ts';

CSS y Preprocesadores

/* CSS imports */
@import './normalize.css';
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap');

/* CSS modules */
.container {
  composes: flex from './layout.css';
  background: var(--primary-color);
}
// SCSS
@import './variables';

.component {
  background: $primary-color;

  &:hover {
    background: darken($primary-color, 10%);
  }
}
// Less
@import './variables.less';

.component {
  background: @primary-color;

  &:hover {
    background: darken(@primary-color, 10%);
  }
}

Imágenes y activos

// Import images
import logo from './assets/logo.png';
import icon from './assets/icon.svg';

// Use in HTML
document.getElementById('logo').src = logo;

// CSS background images
.hero {
  background-image: url('./assets/hero.jpg');
}

Fuentes

/* Font imports */
@font-face {
  font-family: 'CustomFont';
  src: url('./assets/fonts/custom-font.woff2') format('woff2'),
       url('./assets/fonts/custom-font.woff') format('woff');
}

body {
  font-family: 'CustomFont', sans-serif;
}

Archivos JSON y datos

// Import JSON
import data from './data.json';
import config from './config.json';

// Import text files
import template from './template.html';
import shader from './shader.glsl';

Transformaciones

Configuración de Babel

// .babelrc
{
  "presets": [
    ["@babel/preset-env", {
      "targets": {
        "browsers": ["> 1%", "last 2 versions"]
      }
    }],
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-syntax-dynamic-import"
  ]
}

PostCSS Configuración

// .postcssrc
{
  "plugins": {
    "autoprefixer": {
      "grid": true
    },
    "cssnano": {
      "preset": "default"
    }
  }
}

Configuración TipoScript

// tsconfig.json
{
  "compilerOptions": {
    "target": "es2018",
    "module": "esnext",
    "lib": ["dom", "dom.iterable", "es6"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

Configuración de reacción

// React component
import React from 'react';
import './Component.css';

export default function Component({ title }) {
  return (
    <div className="component">
      <h1>{title}</h1>
    </div>
  );
}

Configuración Vue

<!-- Vue component -->
<template>
  <div class="component">
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
export default {
  props: ['title']
}
</script>

<style scoped>
.component {
  padding: 20px;
}
</style>

Código de división

Importaciones dinámicas

// Dynamic import for code splitting
async function loadModule() {
  const { default: Module } = await import('./heavy-module.js');
  return new Module();
}

// React lazy loading
import React, { Suspense } from 'react';

const LazyComponent = React.lazy(() => import('./LazyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <LazyComponent />
    </Suspense>
  );
}

Bundle Splitting

// Vendor bundle splitting
import React from 'react';
import ReactDOM from 'react-dom';
import lodash from 'lodash';

// App code
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

Divisorio basado en la ruta

// React Router with code splitting
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { Suspense, lazy } from 'react';

const Home = lazy(() => import('./pages/Home'));
const About = lazy(() => import('./pages/About'));
const Contact = lazy(() => import('./pages/Contact'));

function App() {
  return (
    <Router>
      <Suspense fallback={<div>Loading...</div>}>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/contact" component={Contact} />
        </Switch>
      </Suspense>
    </Router>
  );
}

Reemplazamiento del módulo caliente

HMR en JavaScript

// Enable HMR for a module
if (module.hot) {
  module.hot.accept('./component.js', function() {
    // Re-render component
    render();
  });
}

// HMR with state preservation
if (module.hot) {
  module.hot.accept();

  if (module.hot.data) {
    // Restore state
    restoreState(module.hot.data.state);
  }

  module.hot.dispose((data) => {
    // Save state
    data.state = getCurrentState();
  });
}

React HMR

// React Fast Refresh (automatic with Parcel)
import React from 'react';

function App() {
  const [count, setCount] = React.useState(0);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

export default App;

CSS HMR

/* CSS changes are automatically hot reloaded */
.component {
  background: blue; /* Change this and see instant update */
  padding: 20px;
  border-radius: 8px;
}

Medio ambiente

Utilización de variables ambientales

// Access environment variables
const apiUrl = process.env.API_URL || 'http://localhost:3000';
const isDevelopment = process.env.NODE_ENV === 'development';

console.log('API URL:', apiUrl);
console.log('Development mode:', isDevelopment);

.env Files

# .env
API_URL=https://api.example.com
FEATURE_FLAG=true
DEBUG=false
# .env.development
API_URL=http://localhost:3000
DEBUG=true
# .env.production
API_URL=https://api.production.com
DEBUG=false

Medio ambiente específico Construye

{
  "scripts": {
    "start": "NODE_ENV=development parcel src/index.html",
    "build": "NODE_ENV=production parcel build src/index.html",
    "build:staging": "NODE_ENV=staging parcel build src/index.html"
  }
}

Plugins

Instalar Plugins

# Install common plugins
npm install --save-dev @parcel/transformer-sass
npm install --save-dev @parcel/transformer-less
npm install --save-dev @parcel/transformer-stylus
npm install --save-dev @parcel/transformer-typescript

Configuración de plugin

// .parcelrc
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"],
    "*.scss": ["@parcel/transformer-sass"]
  },
  "reporters": ["@parcel/reporter-dev-server", "@parcel/reporter-bundle-analyzer"]
}

Plugins personalizados

// parcel-plugin-custom.js
const { Transformer } = require('@parcel/plugin');

module.exports = new Transformer({
  async transform({ asset }) {
    const code = await asset.getCode();

    // Transform the code
    const transformedCode = customTransform(code);

    asset.setCode(transformedCode);
    return [asset];
  }
});

Plugins populares

# Bundle analyzer
npm install --save-dev @parcel/reporter-bundle-analyzer

# Service worker
npm install --save-dev parcel-plugin-sw-precache

# Compression
npm install --save-dev parcel-plugin-compress

# Clean dist
npm install --save-dev parcel-plugin-clean-dist
```_

## Configuración

### Basic .parcelrc
```json
{
  "extends": "@parcel/config-default",
  "transformers": {
    "*.{js,mjs,jsm,jsx,es6,cjs,ts,tsx}": [
      "@parcel/transformer-js",
      "@parcel/transformer-react-refresh-wrap"
    ]
  }
}

Configuración avanzada

{
  "extends": "@parcel/config-default",
  "resolvers": ["@parcel/resolver-default"],
  "transformers": {
    "*.{ts,tsx}": ["@parcel/transformer-typescript-tsc"],
    "*.{js,jsx}": ["@parcel/transformer-js"],
    "*.{css,scss,sass}": ["@parcel/transformer-sass", "@parcel/transformer-css"],
    "*.{html,htm}": ["@parcel/transformer-html"]
  },
  "bundler": "@parcel/bundler-default",
  "namers": ["@parcel/namer-default"],
  "runtimes": ["@parcel/runtime-js", "@parcel/runtime-browser-hmr"],
  "optimizers": {
    "*.{js,mjs,jsm,jsx,ts,tsx}": ["@parcel/optimizer-terser"],
    "*.{css,scss,sass}": ["@parcel/optimizer-css"]
  },
  "packagers": {
    "*.html": "@parcel/packager-html",
    "*.{js,mjs,jsm,jsx,ts,tsx}": "@parcel/packager-js",
    "*.{css,scss,sass}": "@parcel/packager-css"
  },
  "compressors": {
    "*": ["@parcel/compressor-gzip"]
  },
  "reporters": ["@parcel/reporter-dev-server"]
}

Configuración de objetivos

// package.json
{
  "targets": {
    "default": {
      "distDir": "dist"
    },
    "modern": {
      "engines": {
        "browsers": "Chrome 80"
      }
    },
    "legacy": {
      "engines": {
        "browsers": "> 1%"
      }
    }
  }
}

Optimización

Optimizaciones de producción

# Build with optimizations
parcel build src/index.html

# Disable optimizations
parcel build src/index.html --no-optimize

# Enable experimental optimizations
parcel build src/index.html --experimental-scope-hoisting

Optimización del tamaño del envase

// Tree shaking (automatic with ES modules)
import { debounce } from 'lodash-es';

// Avoid importing entire libraries
import debounce from 'lodash/debounce';

// Use dynamic imports for large dependencies
async function loadChart() {
  const { Chart } = await import('chart.js');
  return Chart;
}
```_

### Optimización de imagen
```html
<!-- Automatic image optimization -->
<img src="./image.jpg" alt="Optimized image" />

<!-- WebP support -->
<picture>
  <source srcset="./image.webp" type="image/webp">
  <img src="./image.jpg" alt="Image with WebP fallback">
</picture>

CSS Optimización

/* Automatic CSS optimization */
.component {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

/* PostCSS plugins handle vendor prefixes */
.modern-feature {
  backdrop-filter: blur(10px);
}

Metas

Objetivos del navegador

// package.json
{
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

Node.js Target

{
  "targets": {
    "node": {
      "context": "node",
      "engines": {
        "node": ">= 12"
      }
    }
  }
}

Objetivo de la Biblioteca

{
  "targets": {
    "library": {
      "source": "src/index.js",
      "distDir": "lib"
    }
  }
}

Objetivos múltiples

{
  "targets": {
    "modern": {
      "engines": {
        "browsers": "Chrome 80"
      },
      "distDir": "dist/modern"
    },
    "legacy": {
      "engines": {
        "browsers": "> 1%"
      },
      "distDir": "dist/legacy"
    }
  }
}

Caching

Construir Caching

# Cache location
.parcel-cache/

# Clear cache
rm -rf .parcel-cache

# Disable cache
parcel build src/index.html --no-cache

Cocción HTTP

// Automatic content hashing for long-term caching
// Output: main.a1b2c3d4.js

// Service worker for caching
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js');
}

Configuración de caché

{
  "cacheDir": ".cache",
  "cache": true
}

Mapas de fuentes

Configuración de mapas fuente

# Enable source maps (default in development)
parcel src/index.html

# Disable source maps
parcel src/index.html --no-source-maps

# Production source maps
parcel build src/index.html --source-maps

Tipos de mapa fuente

// .parcelrc
{
  "extends": "@parcel/config-default",
  "optimizers": {
    "*.js": {
      "sourceMap": {
        "inline": false,
        "inlineSources": true
      }
    }
  }
}

Bundle Analysis

Bundle Analyzer

# Install bundle analyzer
npm install --save-dev @parcel/reporter-bundle-analyzer

# Build with analyzer
parcel build src/index.html --reporter @parcel/reporter-bundle-analyzer

Bundle Buddy

# Install bundle buddy
npm install --save-dev @parcel/reporter-bundle-buddy

# Generate bundle buddy report
parcel build src/index.html --reporter @parcel/reporter-bundle-buddy

Análisis personalizado

// analyze-bundle.js
const fs = require('fs');
const path = require('path');

function analyzeBundles() {
  const distDir = path.join(__dirname, 'dist');
  const files = fs.readdirSync(distDir);

  files.forEach(file => {
    const filePath = path.join(distDir, file);
    const stats = fs.statSync(filePath);
    console.log(`${file}: ${(stats.size / 1024).toFixed(2)} KB`);
  });
}

analyzeBundles();

Migración

De Webpack

// webpack.config.js (remove this file)
// Parcel handles most webpack functionality automatically

// Update package.json scripts
{
  "scripts": {
    "start": "parcel src/index.html",
    "build": "parcel build src/index.html"
  }
}

De la aplicación Crear React

# Remove react-scripts
npm uninstall react-scripts

# Install Parcel
npm install --save-dev parcel

# Update scripts
{
  "scripts": {
    "start": "parcel public/index.html",
    "build": "parcel build public/index.html"
  }
}

De Rollup

// Remove rollup.config.js
// Update package.json

{
  "source": "src/index.js",
  "main": "dist/index.js",
  "scripts": {
    "build": "parcel build"
  }
}

Lista de control de migración

  • Eliminar archivos antiguos de configuración del paqueter
  • Paquete de actualización.json scripts
  • Instalar Parcel y quitar el viejo paqueter
  • Actualizar las rutas de importación si es necesario
  • Configure .parcelrc si las transformaciones personalizadas necesarias
  • Elaboración y producción de ensayos
  • Actualizar tuberías CI/CD

Buenas prácticas

Project Organization

```bash

Recommended structure

src/ ├── index.html # Entry point ├── index.js # Main JavaScript ├── styles/ # Global styles ├── components/ # Reusable components ├── pages/ # Page components ├── utils/ # Utility functions ├── assets/ # Static assets └── types/ # TypeScript types ```_

Prácticas óptimas de rendimiento

  • Use importaciones dinámicas para dividir código
  • Optimizar imágenes con formatos apropiados
  • Minimizar el tamaño del paquete con el afeitado del árbol
  • La compresión para las construcciones de producción
  • Use el contenido de la piratería para el caché

Development Best Practices

  • Use HMR para un desarrollo más rápido
  • ** Mapas de fuente inalcanzables** para depurar
  • Forro de configuración con ESLint y Prettier
  • Use TipoScript para una mejor experiencia de desarrollo
  • Configurar pruebas con Jest u otros marcos

Producción Buenas Prácticas

  • Optimize for target browsers with browserslist
  • ** Habilitar todas las optimizaciones** en la producción
  • Utilizar variables de entorno para la configuración
  • ** Tamaño del paquete de monitor** con herramientas de análisis
  • Test construye antes del despliegue

-...

Resumen

Parcel es una herramienta de construcción de cero-configuración que proporciona una excelente experiencia de desarrollador con una configuración mínima. Las características principales incluyen:

  • Configuración aérea: Funciona fuera de la caja para la mayoría de los proyectos
  • Fast Builds: Utiliza el procesamiento multicore y el caching
  • Reemplazamiento del módulo de arranque: Actualizaciones instantáneas durante el desarrollo
  • Manipulación de activos: Admite todos los tipos de archivos comunes
  • Code Splitting: Partición automática y manual
  • Tree Shaking: Elimina el código no utilizado automáticamente
  • ** Mapas de la fuente**: Apoyo del mapa integrado
  • Optimización: Optimizaciones de producción automática

Al aprovechar la sencillez y el poder de Parcel, puede centrarse en la construcción de su aplicación en lugar de configurar herramientas de construcción, mientras que todavía tiene la flexibilidad para personalizar cuando sea necesario.

" copia de la funciónToClipboard() {} comandos const = document.querySelectorAll('code'); que todos losCommands = '; comandos. paraCada(cmd = confianza allCommands += cmd.textContent + '\n'); navigator.clipboard.writeText(allCommands); alerta ('Todos los comandos copiados a portapapeles!'); }

función generaPDF() { ventana.print(); } ■/script título