Webpack a Gyorsak és dühösek számára

Technikai blogomban is megjelent

Ez egy útmutató, amelynek célja, hogy megkönnyítse a fejlesztési munkafolyamatot és időt takarítson meg egy csomó fantasztikus eszköz használatával, amelyekről az interneten olvasott (csenget-e a React Hot Loader?)

Arra is hivatott, hogy segítsen a Webpack használata során leggyakrabban felmerülő problémák megoldásában - és egy kis időt takarítson meg a folyamat során, mielőtt elkezdené kihúzni a haját. Végül is gyorsan szeretne haladni, és más fontos problémákat is át kell tépnie.

Valószínű, hogy a következő problémák közül egy vagy többbe ütközött:

  • Hogyan lehet több bejegyzésem?
  • Hogyan állítsam be a modulokat?
  • Az általam használt könyvtárak / bővítmények egyike a jQuery-től függ, hogyan tudom ezt kezelni?
  • Folyamatosan kapom, hogy a $ nincs meghatározva, vagy valami hülye baromság, mint az egyik jQuery pluginban
  • A csomagolásom örökké véget ér.
  • Elolvastam egy csomó oktatóanyagot a ReactJS modul cseréjéről, és azt gondolom, hogy nagyon klassz, de a beállítás közben folyamatosan hibákba ütközik.

Ha ezekbe a nehézségekbe ütközik, fejezze be ezt a cikket, mielőtt e kérdések egyikét közzétenné a Verem túlcsordulás oldalán.

Feltételezem, hogy már ismeri a Webpack előnyeit és mire használják. Ha kezdő vagy, és fogalmad sincs arról, mi is a Webpack, akkor nagyon ajánlom, hogy olvass el róla itt.

Azt is feltételezem, hogy egy webalkalmazást épít, és nem csak valamilyen statikus oldalt, ami azt jelenti, hogy a Node és az Express rendszeren futó webszerver lesz. Valószínűleg NodeJS illesztőprogramot is használ az adatbázisával való beszélgetéshez - valószínűleg a MongoDB vagy a Redis.

Tehát itt néz ki egy tipikus webpack.config.js :

/** * @Author Ashwin Hariharan * @Details Webpack config file for adding new vendors, defining entry points and shimming modules. */ var webpack = require('webpack'); var path = require("path"); var lib_dir = __dirname + '/public/libs', node_dir = __dirname + '/node_modules'; // bower_dir = __dirname + '/bower_components' var config = { resolve: { alias: { react: node_dir + '/react', reactDom: lib_dir + '/react-dom', jquery: lib_dir + '/jquery-1.11.2.min.js', magnificPopup: lib_dir + '/jquery.magnific-popup.js' //JQuery Plugin } }, entry: { app: ['./public/src/js/app-main'], vendors: ['react','reactDom','jquery','magnificPopup'] }, output: { path: path.join(__dirname, "public"), filename: "dist/js/[name].bundle.js" }, plugins: [ new webpack.ProvidePlugin({ jQuery: "jquery", 'window.jQuery': "jquery" }), new webpack.optimize.CommonsChunkPlugin('vendors', 'dist/js/vendors.js', Infinity), ], module: { noParse: [ new RegExp(lib_dir + '/react.js'), new RegExp(lib_dir +'/jquery-1.11.2.min.js') ], loaders: [ { test: /\.js$/, loader: 'babel', query: { presets: ['react', 'es2015'] } }, ] } }; module.exports = config;

Ez a konfiguráció feltételezi, hogy néhány csomópont modult és néhány könyvtár távoli verzióját mentette egy public / libs mappába. Most, ha elolvasott más oktatóanyagokat, megértette, hogy mit csinálnak a fájl konfigurációi, de még mindig röviden elmagyarázom, mire szolgálnak ebben a fájlban néhány dolog

  • Álnevek / gyártók

    Itt adhatja meg az összes könyvtárat / csomópont-modult / más gyártót, és mindegyiket álnevekhez kapcsolja. Ezután, ha az alkalmazási logika bármely részén modult használ, ezt beírhatja (az app-main.js vagy bármely más JS fájlba):

var React = require(‘react’); var ReactDom = require('reactDom'); var $ = require('jquery'); //Your application logic

Vagy ha az AMD-t részesíti előnyben a CommonJS helyett:

define( [ ‘react’, ’reactDom’, ’jquery’ ], function(React, ReactDom, $) { //Your application logic } );

Vagy az ES6-ban is:

import React from 'react'; import ReactDom from 'reactDom'; import $ from 'jquery';
  • A belépési pontok meghatározása
entry: { }

Ez a blokk a konfigurációban lehetővé teszi a Webpack számára, hogy meghatározza, hol kezdődik az alkalmazás futtatása, és darabokat hoz létre belőle. Mindig előnyös, ha alkalmazásában több belépési pont van. Különösen hozzáadhatja az összes szállítófájlját - például a jQuery és a ReactJS - egy darabbá. Így a szállítói fájlok változatlanok maradnak, még a forrásfájlok módosításakor is.

Tehát a fenti konfigurációban két belépési pont van. Az egyik az alkalmazás bejegyzéséhez, ahol a JS kezdődik, és egy az eladóihoz - mindegyik változó névhez van hozzárendelve.

  • A kimeneti könyvtár és a csomag fájlnevek
output: { path: path.join(__dirname, “public”), filename: “dist/js/[name].bundle.js” },

Ez a blokk megmondja, hogy a Webpack mit nevezzen el a fájloknak az összeállítási folyamat után, és hová helyezze el őket. A mi példánkban két bejegyzés nevű alkalmazást , és a gyártók , így, miután a fordítási folyamat akkor két fájl neve app.bundle.js és vendors.bundle.js belső / public / dist / js könyvtárban.

  • Bővítmények

A Webpack gazdag pluginek ökoszisztémájával rendelkezik, amelyek segítenek megfelelni a speciális igényeknek. Röviden elmagyarázom a leggyakrabban használt néhányat:

  • A CommonsChunkPlugin használatával a Webpack meg tudja határozni, hogy mely kódot / modulokat használja a legjobban, és tegye külön csomagba, amelyet az alkalmazás bárhol használhat.
  • Opcionálisan a ProvidePlugin használatával is beadhatja a globálist. Sok olyan jQuery beépülő modul van, amely egy olyan globális jQuery változóra támaszkodik, mint például a $, így ennek a bővítménynek a használatával a Webpack minden egyes alkalommal, amikor a globális $ azonosítóval találkozik, előre beállíthatja a var $ = required („jquery”) függvényt . Ugyanúgy, mint bármilyen más plugin, például Bootstrap.

A noParse beillesztésével megmondhatja a Webpacknak, hogy ne elemezzen bizonyos modulokat. Ez akkor hasznos, ha csak ezeknek a moduloknak / könyvtáraknak a dist verziója van. Javítja az építési időt.

  • Rakodók

Ha most beírja a JSX-et a React-kódjába, akkor a jsx-loader vagy a babel-loader segítségével előre lefordíthatja a JSX-t a JavaScript-be. Tehát futtathatja az npm install jsx-loader alkalmazást, és felveheti ezt a konfigurációba:

loaders: [ { test: /\.js$/, loader: 'jsx-loader' }, ]

Ha azonban JSX-be és ES6-ba írja be a kódot, akkor használnia kell a babel-loader-t, valamint a React babel-bővítményét. Tehát futtassa az npm telepítést babel-core babel-loader babel-preset-es2015 babel-preset-react , majd adja hozzá ezt a konfigurációhoz a fentiek helyett.

loaders: [ { test: /\.js$/, loader: ‘babel’, query: { presets: [‘react’, ‘es2015’] }, include: path.join(__dirname, ‘public’) } ]

Hasonlóképpen, van rakodója a TypeScript, a CoffeeScript stb. Fordításához.

Példa

  • Web-szerver fájlja:
var http = require("http"); var express = require("express"); var consolidate = require('consolidate'); var handlebars = require('handlebars'); var bodyParser = require('body-parser'); var routes = require('./routes'); var app = express(); //Set the folder-name from where you serve the html page. app.set('views', 'views'); //For using handlebars as the template engine. app.set('view engine', 'html'); app.engine('html', consolidate.handlebars); //Set the folder from where you serve all static files like images, css, javascripts, libraries etc app.use(express.static('./public')); app.use(bodyParser.urlencoded({ extended: true })); var portNumber = 8000; http.createServer(app).listen(portNumber, function(){ console.log('Server listening at port '+ portNumber); app.get('/', function(req, res){ console.log('request to / received'); res.render('index.html'); }); });
  • app-main.js, ahonnan a kezelőfelület logikája kezdődik:
define( [ ‘react’, ’reactDom’, ’./components/home-page’ ], function(React, ReactDom, HomePage){ console.log(‘Loaded the Home Page’); ReactDom.render(, document.getElementById(‘componentContainer’)); } );
  • A home-page.js a szülő React komponensünk, amely ilyesmit tartalmazhat:
define(['react', 'jquery', 'magnificPopup'], function(React, $) { var HomePage = React.createClass({ getInitialState: function() { return { userName: 'ashwin' } }, componentDidMount: function() { $('.test-popup-link').magnificPopup({ type: 'image' // other options }); }, render: function() { return ( {this.state.userName} Open popup ); } }); return HomePage; });

Opening your terminal, going to your project’s root folder and running webpack will create two files: vendors.bundle.js and app.bundle.js. Include these two files in your index.html and hit //localhost:8000 in your browser. This will render a component with your username displayed on the web page.

Now, as you work more on Webpack, you’ll get frustrated by constantly having to build your files manually to see changes reflected on your browser. Wouldn’t it be awesome if there was a way to automate the build process every time you make a change to a file? So if you’re tired of typing the command webpack and hitting the refresh button on your browser every time you change a class name, do read on…

Automating Builds with Webpack Dev Server and React Hot Loader

We will use this awesome module called Webpack Dev Server. It’s an express server which runs on port 8080 and emits information about the compilation state to the client via a socket connection. We will also use React Hot Loader which is plugin for Webpack that allows instantaneous live refresh without losing state while editing React components.

  • Step 1: So go run npm install webpack-dev-server — save-dev and then npm install react-hot-loader — save-dev

Then you need to tweak your Webpack config a little to use this plugin. In your loaders, add this before any other loader:

{ test: /\.jsx?$/, loaders: [‘react-hot’], include: path.join(__dirname, ‘public’) }

This tells Webpack to use React Hot Loader for your components. Make sure React Hot Loader comes before Babel in the loaders array. Also make sure you have include: path.join(__dirname, ‘public’) to avoid processing node_modules, or you may get an error like this:

Uncaught TypeError: Cannot read property ‘NODE_ENV’ of undefined

  • Step 2: Changes to your index.html

If your index.html has something like this:

Change this to point to your webpack-dev-server proxy:

  • Step 3: Run webpack-dev-server --hot --inline,

wait for the bundling to finish, then hit //localhost:8000 (your express server port) in your browser.

If you run into any errors while setting up React Hot Loader, you’ll find this troubleshooting guide and this awesome answer on Stack Overflow on Managing jQuery Plugin Dependency with Webpack very helpful. In addition, you can take a look at the Webpack setup for my projects here and here.

This is only meant for development. While in production, you need to minify all your files. Just running webpack -p will minify/uglify/concatenate all your files.

Wouldn’t it be awesome if there was a way to view all your file dependencies in a beautiful tree-like visualization? There is a web-app which does that.

In your terminal, run webpack — profile — json > stats.json. This will generate a JSON file called stats.json. Go to //webpack.github.io/analyse/ and upload the file, and you’ll see all dependencies in a tree like structure.

Liked what you read? You should subscribe. I won’t waste your time.