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:
您可能会遇到以下一个或多个问题:
I keep getting $ is not defined or some stupid crap like that in one of the jQuery Plugins
我不断得到$未定义,或者在其中一个jQuery插件中出现了一些愚蠢的废话
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等。
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');
});
});
define(
[
‘react’,
’reactDom’,
’./components/home-page’
],
function(React, ReactDom, HomePage){
console.log(‘Loaded the Home Page’);
ReactDom.render( , 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 (
{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 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并在浏览器上单击刷新按钮,请继续阅读...
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具有以下内容:
Change this to point to your webpack-dev-server proxy:
将其更改为指向您的webpack-dev-server代理:
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/