Also published in my tech blog
也發布在我的技術博客中
This is a guide that is meant to help you ease your development workflow and save your time by using a bunch of awesome tools that you’ve read about on the internet (does React Hot Loader ring any bells?)
這是一個指南,旨在通過使用您在互聯網上讀到的一系列很棒的工具來幫助您簡化開發工作流程并節省時間(React Hot Loader會響起什么鐘聲嗎?)
It’s also meant to help you out with some of the most commonly encountered problems while using Webpack — and save some time in the process before you begin to pull your hair out. After all, you want to go fast and tear through other important problems.
它還意味著可以幫助您解決使用Webpack時遇到的一些最常見的問題,并在開始梳理頭發之前節省一些時間。 畢竟,您想快速解決其他重要問題。
Chances are that you’ve run into one or more of the following issues:
您可能會遇到以下一個或多個問題:
- How do I have multiple entries? 我如何有多個條目?
- How do I shim modules? 如何填充模塊?
- One of the libraries/plugins that I use depends on jQuery, how do I handle that? 我使用的庫/插件之一取決于jQuery,我該如何處理?
I keep getting $ is not defined or some stupid crap like that in one of the jQuery Plugins
我不斷得到$未定義,或者在其中一個jQuery插件中出現了一些愚蠢的廢話
- My bundling takes like, forever to finish. 我的捆綁需要永遠完成。
- I read a bunch of tutorials on How Module Replacement for ReactJS and think it’s really cool, but keep running into errors while setting it up. 我閱讀了很多關于ReactJS的模塊替換方法的教程,并認為它確實很酷,但是在設置它時會遇到錯誤。
If you’re running into these difficulties, finish this article before you resort to posting one of these questions on Stack Overflow.
如果遇到這些困難,請先完成本文,然后再在Stack Overflow上發布以下問題之一。
I’m assuming that you already know about the advantages of Webpack and what it is used for. If you’re a beginner and have no clue about what Webpack is, I highly recommend reading about it here.
我假設您已經了解Webpack的優勢及其用途。 如果您是初學者,不了解Webpack是什么,我強烈建議您在此處閱讀有關內容。
I’m also assuming that you’re building a web app and not just some static page, which means that you will have a web server running on Node and Express. You most likely also use a NodeJS driver to talk to your database — probably MongoDB or Redis.
我還假設您正在構建一個Web應用程序,而不僅僅是一些靜態頁面,這意味著您將在Node和Express上運行一個Web服務器。 您很可能還會使用NodeJS驅動程序與數據庫進行對話-可能是MongoDB或Redis。
So here is what a typical webpack.config.js looks like:
因此,典型的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;
This config assumes that you have use some node modules and dist version of few libraries saved inside a public/libs folder. Now if you’ve read other tutorials, you understand what the configs in this file do, however I’m still gonna briefly explain what few things in this file are for —
此配置假定您已經使用了一些節點模塊和保存在public / libs文件夾中的少量庫的dist版本。 現在,如果您已閱讀其他教程,您將了解此文件中的配置的作用,但是,我仍然要簡要解釋一下該文件中的一些內容-
Aliases / vendors
別名/供應商
Here is where you include all of your libraries/node modules/other vendors and map each of them to aliases. Then if you use a module in any part of your application logic, you can write this (in your
在這里,您包括所有庫/節點模塊/其他供應商,并將它們映射到別名。 然后,如果您在應用程序邏輯的任何部分使用模塊,則可以編寫此代碼(在
app-main.js or any other JS file):
app-main.js或任何其他JS文件):
var React = require(‘react’);
var ReactDom = require('reactDom');
var $ = require('jquery');//Your application logic
Or if you prefer AMD over CommonJS:
或者,如果您更喜歡AMD而不是CommonJS:
define([‘react’,’reactDom’,’jquery’],function(React, ReactDom, $) {//Your application logic}
);
Or in ES6 too:
還是在ES6中:
import React from 'react';
import ReactDom from 'reactDom';
import $ from 'jquery';
Defining your entry points
定義入口點
entry: {}
This block in your config allows Webpack to determine where your app begins execution, and it creates chunks out of it. Having multiple entry points in your application is always advantageous. In particular, you can add all your vendor files — like jQuery and ReactJS — into one chunk. This way, your vendor files will remain the same, even when you modify your source files.
配置中的此塊允許Webpack確定應用在何處開始執行,并從中創建塊。 在您的應用程序中擁有多個入口點總是有利的。 特別是,您可以將所有供應商文件(例如jQuery和ReactJS)添加到一個塊中。 這樣,即使修改源文件,您的供應商文件也將保持不變。
So in the above config, there are two entry points. One for your app’s entry where your JS begins, and one for your vendors — each of them mapped to a variable name.
因此,在上面的配置中,有兩個入口點。 一個用于您的JS開始的應用程序條目,另一個用于您的供應商-每個供應商都映射到一個變量名。
Your output directory and bundle file names
您的輸出目錄和捆綁文件名
output: {path: path.join(__dirname, “public”),filename: “dist/js/[name].bundle.js”},
This block tells Webpack what to name your files after the build process, and where to place them. In our example we have two entries named app and vendors, so after the build process you’ll have two files called app.bundle.js and vendors.bundle.js inside /public/dist/js directory.
此塊告訴Webpack在構建過程后要命名文件的名稱以及放置位置。 在我們的例子中,我們有一個名為應用程序和供應商兩個條目,所以之后的構建過程中您將有兩個文件名為app.bundle.js和vendors.bundle.js內部/公共/距離/ JS目錄。
Plugins
外掛程式
Webpack comes with a rich ecosystem of plugins to help meet specific needs. I’ll briefly explain few of the most commonly used ones:
Webpack帶有豐富的插件生態系統,可幫助滿足特定需求。 我將簡要解釋一些最常用的方法:
Use the CommonsChunkPlugin to have Webpack determine what code/modules you use the most, and put it in a separate bundle to be used anywhere in your application.
使用CommonsChunkPlugin讓Webpack確定您最常使用的代碼/模塊,并將其放在單獨的捆綁軟件中,以在應用程序中的任何地方使用。
You can optionally use the ProvidePlugin to inject globals. There are many jQuery plugins that rely on a global jQuery variable like $, so by using this plugin Webpack can prepend var $ = require(“jquery”) every time it encounters the global $ identifier. Ditto for any other plugin out there, like Bootstrap.
您可以選擇使用ProvidePlugin注入全局變量。 有很多jQuery插件都依賴$之類的全局jQuery變量,因此,使用此插件,Webpack每次遇到全局$標識符時都可以在var $ = require(“ jquery”)之前添加var $ = require(“ jquery”) 。 同上其他任何插件,例如Bootstrap。
By including noParse, you can tell Webpack not to parse certain modules. This is useful when you only have the dist version of these modules/libraries. Improves build time.
通過包含noParse,您可以告訴Webpack不要解析某些模塊。 當您只有這些模塊/庫的發行版時,此功能很有用。 縮短構建時間。
Loaders
裝載機
Now if you write JSX in your React code, you can either use the jsx-loader or babel-loader to pre-compile JSX into JavaScript. So you can run npm install jsx-loader and include this in your config:
現在,如果您在React代碼中編寫JSX,則可以使用jsx-loader或babel-loader將JSX預編譯為JavaScript。 因此,您可以運行npm install jsx-loader并將其包含在您的配置中:
loaders: [{ test: /\.js$/, loader: 'jsx-loader' },
]
However, if you write your code in JSX and ES6, then you’ll need to use the babel-loader, along with the babel plugin for React. So run npm install babel-core babel-loader babel-preset-es2015 babel-preset-react and then add this to your config instead of the above.
但是,如果您使用JSX和ES6編寫代碼,則需要使用babel-loader和React的babel插件。 因此,運行npm install babel-core babel-loader babel-preset-es2015 babel-preset-react ,然后將其添加到您的配置中,而不是上面的配置。
loaders: [{ test: /\.js$/, loader: ‘babel’,query: {presets: [‘react’, ‘es2015’]},include: path.join(__dirname, ‘public’)}
]
Likewise, you have loaders to compile TypeScript, CoffeeScript, etc.
同樣,您也可以使用加載程序來編譯TypeScript,CoffeeScript等。
例 (Example)
- Your web-server file: 您的網絡服務器文件:
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 from where our front-end logic begins: app-main.js從我們的前端邏輯開始:
define([‘react’,’reactDom’,’./components/home-page’],function(React, ReactDom, HomePage){ console.log(‘Loaded the Home Page’);ReactDom.render(<HomePage />, document.getElementById(‘componentContainer’));}
);
home-page.js is our parent React component which could contain something like this:
home-page.js是我們的父React組件,其中可能包含以下內容:
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 (<div id="homePage">{this.state.userName}<a className="test-popup-link" href="path-to-image.jpg">Open popup</a></div>);}});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 http://localhost:8000 in your browser. This will render a component with your username displayed on the web page.
打開你的終端,去你的項目的根文件夾,運行的WebPack將創建兩個文件:vendors.bundle.js和app.bundle.js。 將這兩個文件包含在index.html中,然后在瀏覽器中單擊http:// localhost:8000 。 這將使用您的用戶名顯示在網頁上呈現一個組件。
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…
現在,當您在Webpack上進行更多工作時,您將不得不不斷地手動構建文件以查看反映在瀏覽器中的更改而感到沮喪。 如果每次更改文件時都存在一種使構建過程自動化的方法,那豈不是很棒嗎? 因此,如果您在每次更改類名時都厭倦了鍵入命令webpack并在瀏覽器上單擊刷新按鈕,請繼續閱讀...
使用Webpack Dev Server和React Hot Loader自動化構建 (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.
我們將使用稱為Webpack Dev Server的出色模塊。 它是一個運行在端口8080上的快速服務器,并通過套接字連接將有關編譯狀態的信息發送給客戶端。 我們還將使用React Hot Loader ,它是Webpack的插件,允許即時實時刷新而在編輯React組件時不會丟失狀態。
Step 1: So go run npm install webpack-dev-server — save-dev and then npm install react-hot-loader — save-dev
第1步 :運行npm install webpack-dev-server-save-dev ,然后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:
然后,您需要稍微調整Webpack配置以使用此插件。 在您的加載程序中,在其他任何加載程序之前添加此代碼:
{ 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:
這告訴Webpack為您的組件使用React Hot Loader。 確保React Hot Loader在裝載器陣列中排在Babel之前。 還要確保您包括:path.join(__ dirname,'public')以避免處理node_modules,否則您可能會得到如下錯誤:
Uncaught TypeError: Cannot read property ‘NODE_ENV’ of undefined
未捕獲的TypeError:無法讀取未定義的屬性'NODE_ENV'
Step 2: Changes to your index.html
第2步 :更改為index.html
If your index.html has something like this:
如果您的index.html具有以下內容:
<script src="/dist/js/vendors.js"></script>
<script src="/dist/js/app.bundle.js"></script>
Change this to point to your webpack-dev-server proxy:
將其更改為指向您的webpack-dev-server代理:
<script src="http://localhost:8080/dist/js/vendors.js"></script>
<script src="http://localhost:8080/dist/js/app.bundle.js"></script>
Step 3: Run webpack-dev-server --hot --inline,
步驟3:運行webpack-dev-server --hot --inline ,
wait for the bundling to finish, then hit http://localhost:8000 (your express server port) in your browser.
等待捆綁完成,然后在瀏覽器中點擊http:// localhost:8000 (您的快速服務器端口)。
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.
如果在設置React Hot Loader時遇到任何錯誤,您會發現此疑難解答指南以及有關使用Webpack管理jQuery插件依賴項的 Stack Overflow方面的出色解答 。 另外,您可以在此處和此處查看我的項目的Webpack設置。
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.
這僅是為了發展。 在生產中,您需要縮小所有文件。 只需運行webpack -p即可縮小/合并/合并所有文件。
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 http://webpack.github.io/analyse/ and upload the file, and you’ll see all dependencies in a tree like structure.
在您的終端中,運行webpack — profile — json> stats.j son。 這將生成一個名為stats.json的JSON文件。 轉到http://webpack.github.io/analy se /并上傳文件,您會在樹狀結構中看到所有依賴項。
Liked what you read? You should subscribe. I won’t waste your time.
喜歡您閱讀的內容嗎? 您應該訂閱 。 我不會浪費你的時間。
翻譯自: https://www.freecodecamp.org/news/webpack-for-the-fast-and-the-furious-bf8d3746adbd/