Beginner’s guide to Webpack
Or what I wish I knew when starting with Wepback.“webpack初学者指南
或者说当我开始学习webpack的时候,我想了解的”
本文翻译自Nader Dabit的文章,原文地址
https://medium.com/@dabit3/beginner-s-guide-to-webpack-b1f1a3638460#.hl27r5tvz
注:由于我英语水平有限,所有内容都是提供双语,大家可自行核对。
我在学习时的所有源码都可以在 https://github.com/PHPLARAVEL/webpack-react-starter.git
下载
点击这里获取最新的源代码(本文的源代码都在这里,如果仅仅想了解下可直接下载源码,推荐使用node命令自己安裝包)
webpack在前端中最新和最伟大的工具之一.webpack是一个模块儿打包工具,它可以很好的与最新的前端开发流程包括Babel,ReactJs,CommonJS等等.作为一个webpack的初学者,这些是我们必须要了解的.
这个小教程已经更新并使用了Babel 6.
Webpack公认约定
webpack最好使用npm而不是Bower
使用模块化系统(AMD,CommonJs,ES6)
全局安装Webpack
npm install webpack -g
在你的网站配置根目录创建两个文件:index.html 和 app.js
在app.js中:
document.write('welcome to my app');
console.log('app loaded');
在index.html中:
<html>
<body>
<script src="bundle.js">script>
body>
html>
然后在终端输入:
webpack ./app.js bundle.js
上面这行命令,使用了webpack中的命令webpack.命令中app.js是我们创建的文件,bundle.js是我们希望webpack为我们创建的文件.
执行完这个命令会在帮我们创建一个bundle.js文件,这就是你创建的第一个budle文件啦!还是比较简单吧!
在webpack中的配置文件就是一个基本的common.js模块儿.这个配置文件中描述了所有你的配置项,加载器(稍后解释),和其他的与你的构建具体信息.
在根目录中创建一个文件webpack.config.js,并输入一下code:
module.exports = {
entry: "./app.js",
output: {
filename: "bundle.js"
}
}
entry —–我们的构建的最顶层文件,可以是一个文件,也可一用数组声明一组多个文件.在这该小教程中,我们仅使用一个主文件(app.js)
output—-是一个包含了你的输出配置的对象.在我们的构建中,我们仅标明了文件的key,这个文件就是我们希望webpack创建的bundle.js.
现在就可一启动我们的应用,到命令窗中输入
webpack
一旦我们定义了webpack的配置文件,webpack命令就会基于我们定义的可靠的配置来创建应用.
利用监听模式,Webpack可以监听你的文件,当其中一个文件发生变化,它就会立刻重新构建并生成你的输出文件
There are 2 ways to enable watchmode
有两种方式可以实现监听
webpack --watch
根据我的操作结果理解,这里使用webpack –watch后当你改变你的文件后,你的bundle文件内容不会立马改变,重构的bundle文件存在内存中,当你刷新浏览器时就可以看见改变了.所以这里只有监听,并没有热加载.改变bundle文件内容实在加载后将内存的数据更新到bundle中的
module.exports = {
entry: "./app.js",
output: {
filename: "bundle.js"
},
watch: true
}
当”watch”赋值为”true”后,回到webpack命令中,webpack会在任何文件发生变化时重新构建你的bundle,
此处和上面一样
Webpack有一个网络服务叫webpack-dev-server
可以在命令行中全局安装
npm install webpack-dev-server -g
在命令行中输入
webpack-dev-server
现在你去 http://localhost:8080/webpack-dev-server/,就会看你的应用跑起来了,并输出了所有的日志信息.
从webpacp文档中:
“The dev server uses Webpack’s watch mode. It also prevents webpack from emitting the resulting files to disk. Instead it keeps and serves the resulting files from memory.” — This means that you will not see the webpack-dev-server build in bundle.js, to see and run the build, you must still run the webpack command.
这个开发服务器用了Webpack的监听模式.它也防止webpack输出结果结果到硬盘.取而代之的是,将所得的文件从内存中保存.
这就是说你不会看到 webpack-dev-server 构建bundle.js,要查看和运行这个构建,你必须运行webpack命令
当Webpack开发服务器运行时,你将会发现,如果回到应用改动一下文件,浏览器就会自动的刷新(这就是”热加载”)
默认hot-loading是开启的,要想关闭hot-loading 和 从顶层移除程序的就绪状态,就删除”/webpack-dev-server/ “,直接访问 http://localhost:8080/
要开启”热加载”并在顶层移除应用的就绪状态,关闭webpack开发服务器,并在命令行输入:
webpack-dev-server --inline
Navigate to http://localhost:8080/
去查看这个地址
你会发现”热加载”仍然有效,但状态栏却没有了
这个”热加载”还是挺好玩的,结合phpstorm写完代码不用自动保存,浏览器启动更新.就是在实际项目中,都不能用这个服务,不知到有没有其他方法可以让浏览器自动刷新,因为还有php.要是全部是js就应该没问题了
添加logger.js文件到项目中
在logger.js中输入
console.log('logger.js is now loaded...');
在app.js文件顶部中,增加下面的代码去加载logger.js文件
require('./logger');
现在关闭再重新回到webpack开发服务器,当你重新加载http://localhost:8080/webpack-dev-server/时,你会看到’logger.js is now loaded’ 已经被添加日志到 console 中.
这里根据我的操作,如果开启了热加载,添加完文件后是不需要关闭并回到webpack服务器的,也不需要重新加载,你就可以看到新增的日志信息
增加一个名叫global.js的文件到你的项目中
在global.js中,增加下面的代码
console.log('global.js is now loaded...');
Now, open webpack.config.js, and make the entry key an array:
现在,打开webpack.config.js,并且将入口配置键设置成如下数组:
module.exports = {
entry: ["./global.js", "./app.js"],
output: {
filename: "bundle.js"
}
}
关闭并再次启动webpack-dev-server,刷新http://localhost:8080/webpack-dev-server/,你会发现’gloabal.js’已经加载并输出了日志.
加载器是webpack用来扩展新的放的方法的
From the documentation: “Loaders allow you to preprocess files as you require() or “load” them. Loaders are kind of like “tasks” are in other build tools, and provide a powerful way to handle frontend build steps. Loaders can transform files from a different language like CoffeeScript to JavaScript, or inline images as data URLs. Loaders even allow you to do things like require() css files right in your JavaScript!”
文档中这样讲:
加载器可以让你在require()或者加载文件时预先处理这些文件.加载器有些像其他编译器里面的”任务”,在处理前端编译步骤方面提供了强大的功能.加载器可以将不同的语言进行转换,例如将CoffeeScript转换为JavaScript,或者内联的图片文件转换为Urls数据.加载器甚至可以让你做一些如通过require()方法来加载css到你的JavaScript中1
下面,我们将安装和使用两种装载机:babel和jshint。在我们开始使用这些装载机前,我们会安装一些NPM模块。首先,使用NPM init(当提示你要输入一些信息时,全部选”yes”)来创建一个package.json文件。然后在终端,键入以下内容:
npm install babel-core babel-loader jshint jshint-loader node-libs-browser babel-preset-es2015 babel-preset-react webpack --save-dev
babel-core是babel的npm模块
babel-loader是babel模块的webpack加载器
jshint可以帮助检JavaScript代码测错误和潜在问题的工具
jshint-loader是jshint的webpack加载器
node-libs-browser和webpack是相互依赖的,它为浏览器的使用提供了特定的Node库
babel-preset-es2015可以为所有es2015插件进行babel预设
babel-preset-react可以为所有React插件进行babel预设
— save-dev将这些模块保存为开发依赖项
现在我们已经安装好了babel,我么可以写一些es6代码,然后配置babel的加载器.
1.打开logger.js.删除console.log的这段代码,改成下面的代码:
let checkName= (firstName, lastName) => {
if(firstName !== 'nader' || lastName !== 'dabit') {
console.log('You are not Nader Dabit');
} else {
console.log('You are Nader Dabit');
}
}
checkName(‘nader’, ‘jackson’);
2.将logger.js改成logger.es6
3.打开webpack.config.js并添加babel加载器.在Webpack中增加一个加载器,你必须要先创建一个叫module的key,而module十一个对象.在这个对象中,增加一个key叫loader,它十一个数组.在这个数组中,为每一个加载器创建一个对象.下面已经为babel加载器添加了配置信息:
module.exports = {
entry: ["./global.js" , "./app.js"],
output: {
filename: "bundle.js"
},
module: {
loaders: [
{
test: /\.es6$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015']
}
}
]
},
resolve: {
extensions: ['', '.js', '.es6']
},
}
正如你所见到的,我们已经为我们的第一个加载器添加了三个键名
test–一个正则表达式,用来检测那些文件需要通过加载器处理.如你所见,我们添加了一个表达式检测所有扩展名为”es6”的文件.
exclude (排除)–那些文件加载器将会排除或者说忽略的.我们添加了node_modules这个文件夹.
loader(加载器)–我们将要使用的加载器(这里是babel-loader)
您可以通过将它们写成查询字符串或使用查询属性作为选项传递给给加载程序 cacheDirectory (缓存目录)–默认为false,当设定后,该文件家将作为加载器的结果.以后webpack的整个构建会尝试从这个缓存目录中读取以避免在每一次运行的潜且费时的Babel重新编译过程
presets –让我们使用之前安装的react和es2015预置
我们还添加了一个名为”resolve”的key到我们的配置文件的 module.exports对象中.resolve可以让我们表明那些文件在编程时不许要特别的表明文件扩展名.让我们可以进行如下的表达式:
require('./logger');
instead of:
来替换
require(‘./logger.es6’);
我们已经给‘resolve’ 添加了一个”extensions”key,我们给这个数组添加了三个类型的扩展名
回到项目的Webpack.关闭并通过键入 webpack-dev-server重新启动网络服务器,你会在编译输出框中看到”You are not Nader Dabit”
Congrats, you are now running babel with Webpack!
恭喜!你现在已经将babel和Webpack结合使用啦!
我们将用 JSHint 作为一个预加载器.如你所想,预加载器在加载器之前运行.首先,对你的webpack.config.js文件增加一个preLoaders的键,如下:
module.exports = {
entry: ["./global.js" , "./app.js"],
output: {
filename: "bundle.js"
},
module: {
preLoaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'jshint-loader'
}
],
loaders: [
{
test: /\.es6$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
cacheDirectory: true,
presets: ['react', 'es2015']
}
}
]
},
resolve: {
extensions: ['', '.js', '.es6']
}
}
关闭并重启 webpack-dev-server.你就可以看到一个错误信息
该警告是一个求值错误,表明jshint已经在运行了
这实际上是一个npm的特性和可以在package.json文件中使用的方法,它可以是你的编程变得更简单
在你的package.json文件中,有意个叫做scripts的key.删除该key的值,并替换成如下内容:
"scripts": {
"start": "webpack-dev-server"
},
现在,当你需要运行webpack-dev-server,你可一执行下面的命令来替换:
npm start
当我们在以后的开发中需要在webpack-dev-server执行更多的命令时,这个方法将更有意义.
运行生产的构建,用webpack压缩你的代码,可以在使用Webpack命令时加上 -p 参数
webpack -p
这样就会生成一个压缩后的构建
在工作时我们可以创建不同的配置文件,来对应的生成生产的和开发的构建
Install strip-loader:
安装strip-loader:
npm install strip-loader --save-dev
strip-loader是一个可以用来从你的生产构建的代码中删除指定函数的加载器(我们稍后就将使用)
创建一个webpack-production.config.js文件
In webpack-production.config.js, write the following code:
var WebpackStripLoader = require('strip-loader');
var devConfig = require('./webpack.config.js');
var stripLoader = {
test: [/\.js$/, /\.es6$/],
exclude: /node_modules/,
loader: WebpackStripLoader.loader('console.log')
}
devConfig.module.loaders.push(stripLoader);
module.exports = devConfig;
var stripLoader — 创建一个新的项目,和之前一样增加了test键和exclude键.有用的就是下面这一句
loader:WebpackStripLoader.loader('console.log')
我们告诉 strip-loader 从构建中删除任何使用了console.log句子.WebpackStripLoader.loader() 可以添加任意数目的参数
4. devConfig.module.loaders.push(stripLoader); — we push the new object into our loaders array from our original config.
我们将新的对象添加到配置文件中(该配置文件为原生的配置文件)
5. module.exports = devConfig; — we export our new config object
生成新的配置文件对象
在终端,运行:
webpack --config webpack-production.config.js -p
这里在我的操作中发现,如果使用上面的命令,似乎不会启动网络服务,运行
webpack-dev-server –config webpack-production.config.js -p 就行了
运行webpack并增加config参数,可以让我们指定自定义的配置文件. -p 压缩生产环境的代码
打开bundle.js.你可以用查找来检测,这里面没有console.log的语法.
我们已经将Webpack配置好了.,现在结合React
首先,在终端输入以下命令安装
npm install react --save
接下来,创建一个 hello.js文件,添入一下代码:
import React from "react";
export default React.createClass({
render: function() {
return (
Hello, {this.props.name}!
);
},
});
打开app.js.删除app.js的内容,替换成如下代码,
import React from "react";
import Hello from "./hello";
React.render(
"World" />,
document.body
);
打开 webpack.config.js,改变 babel-loader的test键为如下的数组:
loaders: [
{
test: [/\.js$/, /\.es6$/],
exclude: 'node_modules',
loader: 'babel-loader'
}
]
这样,我们可以让.js和.es6文件都通过babel编译,是我们可以使用jsx语法
重新运行webpack-dev-server,你就会看到效果啦!
注:翻译时React版本是0.14.7的,所以需要安装react-dom
npm install react react-dom –save,
然后在app.js和hello.js中的加载react的下面添加,
import ReactDom from “react-dom”;
运行后如果提示document.body警告,则需要将app.js中的
ReactDom.render(
"World" />,
document.body
);
替换成
ReactDom.render(
"World" />,
document.getElementById('main')
);
并将index.html修改为:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>title>
head>
<body>
<div id="main">div>
<script src="bundle.js">script>
body>
html>
最终的代码资源可以在这里下载
谢谢阅读,如有疑问,请留言!
@dabit3.我是一个@schoolstatusapp的程序员.如果你新欢这篇文章,请推荐并分享它.谢谢!