一份关于webpack2和模块打包的新手指南(一)
webpack已成为现代Web开发中最重要的工具之一。它是一个用于JavaScript的模块打包工具,但是它也可以转换所有的前端资源,例如HTML和CSS,甚至是图片。它可以让你更好地控制应用程序所产生的HTTP请求数量、允许你使用其他资源的特性(例如Jade、Sass和ES6)。webpack还可以让你轻松地从npm下载包。
本文主要针对那些刚接触webpack的同学,将介绍初始设置和配置、模块、加载器、插件、代码分割和热模块替换。
在继续学习下面的内容之前需要确保你的电脑中已经安装了Node.js。
初始配置
使用npm初始化一个新项目并安装webpack:
mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack@beta --save-dev
mkdir src
touch index.html src/app.js webpack.config.js
编写下面这些文件:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello webpack</title>
</head>
<body>
<div id="root"></div>
<script src="dist/bundle.js"></script>
</body>
</html>
// src/app.js
const root = document.querySelector('#root')
root.innerHTML = `<p>Hello webpack.</p>`
// webpack.config.js
const webpack = require('webpack')
const path = require('path')
const config = {
context: path.resolve(__dirname, 'src'),
entry: './app.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
use: [{
loader: 'babel-loader',
options: {
presets: [
['es2015', { modules: false }]
]
}
}]
}]
}
}
module.exports = config
上面的配置是一个普通的出发点,它通知webpack将入口文件src/app.js
编译输出到文件/dist/bundle.js
中、使用babel将所有的.js
文件从ES2015转换成ES5。
为了让它可以转换到ES5格式的JS文件,我们需要安装三个包:babel-core
、webpack加载器babel-loader
和预置babel-preset-es2015
。使用{ modules: false }
让Tree Shaking 从打包文件中删除未使用的导出项(exports)以减少文件大小。
npm install babel-core babel-loader babel-preset-es2015 --save-dev
最后,用以下内容替换package.json
的scripts
部分:
"scripts": {
"start": "webpack --watch",
"build": "webpack -p"
},
在命令行中运行npm start
将以监视模式启动webpack,当src
目录中的.js
文件更改时,它将重新编译bundle.js。控制台中的输出展示了打包文件的信息,注意打包文件的数量和大小十分重要。
现在当你在浏览器中加载index.html页面时会看到"Hello webpack."。
open index.html
打开dist/bundle.js
文件看看webpack都做了哪些事情,顶部是webpack的模块引导代码,底部是我们的模块。到目前为止,你可能对于这个还没有一个深刻的印象。但是现在你可以开始编写ES6模块,webpack将生成适用于所有浏览器的打包文件。
使用 Ctrl + C
停止webpack,运行npm run build
以生产模式编译我们的bundle.js
。
注意,打包文件的大小从2.61 kB减少到了585字节。再看一下dist/bundle.js
文件,你会看到大量难懂的代码,因为我们使用UglifyJS压缩了它。这样的话,我们可以使用更少的代码达到与之前一样的效果。
模块
优秀的webpack知道如何使用各种格式的JavaScript模块,最著名的两个是:
- ES2015
import
语句 - CommonJS
require()
语句
我们可以通过安装、导入lodash来测试这些格式的模块。
npm install lodash --save
// src/app.js
import {groupBy} from 'lodash/collection'
const people = [{
manager: 'Jen',
name: 'Bob'
}, {
manager: 'Jen',
name: 'Sue'
}, {
manager: 'Bob',
name: 'Shirley'
}, {
manager: 'Bob',
name: 'Terrence'
}]
const managerGroups = groupBy(people, 'manager')
const root = document.querySelector('#root')
root.innerHTML = `<pre>${JSON.stringify(managerGroups, null, 2)}</pre>`
运行npm start
启动webpack并刷新index.html,你可以看到一个根据manager分组的数组。
让我们将这个数组转移到它自己的模块people.js
中。
// src/people.js
const people = [{
manager: 'Jen',
name: 'Bob'
}, {
manager: 'Jen',
name: 'Sue'
}, {
manager: 'Bob',
name: 'Shirley'
}, {
manager: 'Bob',
name: 'Terrence'
}]
export default people
我们可以在app.js
中使用相对路径轻松的导入它。
// src/app.js
import {groupBy} from 'lodash/collection'
import people from './people'
const managerGroups = groupBy(people, 'manager')
const root = document.querySelector('#root')
root.innerHTML = `<pre>${JSON.stringify(managerGroups, null, 2)}</pre>`
注意:像lodash/collection
这样没有相对路径的导入是导入安装在/node_modules
的模块,你自己的模块需要一个类似./people
的相对路径,你可以以此区分它们。
加载器
我们已经介绍过,你可以通过配置像babel-loader
这样的加载器来告诉webpack在遇到不同文件类型的导入时该怎么做。你可以将多个加载器组合在一起,应用到很多文件转换中。在JS中导入.sass
文件是一个非常的例子。
Sass
这种转换涉及三个单独的加载器和node-sass
库:
npm install css-loader style-loader sass-loader node-sass --save-dev
在配置文件中为.scss
文件添加新规则。
// webpack.config.js
rules: [{
test: /\.scss$/,
use: [
'style-loader',
'css-loader',
'sass-loader'
]
}, {
// ...
}]
注意: 任何时候更改webpack.config.js
中的任意一个加载规则都需要使用Ctrl + C
和npm start
重新启动构建。
加载器序列以相反的顺序进行处理:首先sass-loader
将Sass转换为CSS;然后css-loader
将CSS解析为JavaScript并解析所有依赖;最后style-loader
将我们的CSS输出到文档中的标签。
你可以将它们看作函数调用,将一个加载器的输出输入到下一个加载器中。
styleLoader(cssLoader(sassLoader('source')))
添加一个sass源文件:
/* src/style.scss */
$bluegrey: #2B3A42;
pre {
padding: 20px;
background: $bluegrey;
color: #dedede;
text-shadow: 0 1px 1px rgba(#000, .5);
}
你现在可以直接在JavaScript中导入Sass文件。
// src/app.js
import './style.scss'
// ...
重新加载index.html,你应该会看到一些样式。
JS中的CSS
我们刚刚在JavaScript中将一个sass文件作为模块导入了。
打开dist/bundle.js
并搜索“pre {”
。事实上,我们的sass已被编译成一串CSS,并作为一个模块保存在我们的打包文件中。当我们将这个模块导入JavaScript中时,style-loader
会将这个字符串输入到嵌入的<style>
标签中。
我知道你在想什么---为什么?
我不会在这里过多的讨论这个问题,但这里有几个值得了解的原因:
- 你想要包含在项目中的JavaScript组件可能依赖于其他资源才能正常运行(HTML,CSS,图片,SVG),如果这些资源都可以打包在一起,那么导入和使用将会更容易。
- 消除死代码:当你的代码不再导入JS组件时,CSS也将不再被导入。生成的打包文件将只会包含执行某些操作的代码。
- CSS模块:CSS的全局命名空间很难保证对CSS的更改不会产生任何副作用。CSS模块通过将CSS默认设置为本地命名空间、提供可以在JavaScript中引用的唯一类名来更改这一模式。
- 通过打包、分割代码等巧妙的方式来减少HTTP请求的数量。
图片
加载器的最后一个例子是使用url-loader
处理图片。
在标准的HTML文档中,当浏览器遇到<img>
标签或具有background-image
属性的元素时将请求图片。你可以使用webpack将图片存储为JavaScript字符串来对小图片进行优化处理。这样你就可以预先加载它们,并且浏览器不必在以后为其单独发起请求。
npm install file-loader url-loader --save-dev
添加一个加载图片的规则:
// webpack.config.js
rules: [{
test: /\.(png|jpg)$/,
use: [{
loader: 'url-loader',
options: { limit: 10000 } // 将大小小于10kb的图片转为base64字符串
}]
}, {
// ...
}]
使用Ctrl + C
和npm start
重新启动构建。
运行下面的命令下载测试图片:
curl https://raw.githubusercontent.com/sitepoint-editors/webpack-demo/master/src/code.png --output src/code.png
现在可以在app.js的顶部导入图片:
// src/app.js
import codeURL from './code.png'
const img = document.createElement('img')
img.src = codeURL
img.style.backgroundColor = "#2B3A42"
img.style.padding = "20px"
img.width = 32
document.body.appendChild(img)
// ...
这样将引入一个图片,其中src属性包含图片本身的数据URL。
<img src="data:image/png;base64,iVBO..." style="background: #2B3A42; padding: 20px" width="32">
此外,由于css-loader
保障了使用url()引用的图片也可以通过url-loader
运行,所以可以直接在CSS中内联它。
/* src/style.scss */
pre {
background: $bluegrey url('code.png') no-repeat center center / 32px 32px;
}
编译成这样:
pre {
background: #2b3a42 url("data:image/png;base64,iVBO...") no-repeat scroll center center / 32px 32px;
}
静态资源模块
你现在应该可以明白加载器是如何建立各种资源之间的依赖关系的。
这其实也就是webpack主页上的图片所展示的那样:
虽然JavaScript是入口点,但是webpack认为其他类型资源(如HTML,CSS和SVG)都有自己的依赖关系,所以这些类型的资源应该被视为构建过程的一部分。
一份关于webpack2和模块打包的新手指南(一)的更多相关文章
- 一份关于webpack2和模块打包的新手指南(二)
插件 我们已经看到一个内置的webpack插件的例子,在npm run build脚本中调用的webpack -p命令就是使用webpack附带的UglifyJsPlugin插件以生产模式压缩打包文件 ...
- 一份关于webpack2和模块打包的新手指南
webpack已成为现代Web开发中最重要的工具之一.它是一个用于JavaScript的模块打包工具,但是它也可以转换所有的前端资源,例如HTML和CSS,甚至是图片.它可以让你更好地控制应用程序所产 ...
- js模块化/js模块加载器/js模块打包器
之前对这几个概念一直记得很模糊,也无法用自己的语言表达出来,今天看了大神的文章,尝试根据自己的理解总结一下,算是一篇读后感. 大神的文章:http://www.css88.com/archives/7 ...
- Zepto自定义模块打包构建
文章转自 http://www.chengxuyuans.com/web_technology/zeptojs-build.html zepto.js 是个好东西,遵循 jQuery API,但比 j ...
- 探索 模块打包 exports和require 与 export和import 的用法和区别
菜单快捷导航: CommonJS 之 exports和require用法 ES6 Module 之 export 和 import 用法 CommonJS和ES6 Module的区别 循环依赖 和 解 ...
- 多模块打包后,扫描不到@controller和@service,实现 ADD DIRECTORY ENTRIES
多模块打包后,扫描不到@controller和@service等Bean. 原因:打包时没有生成目录信息 解决办法: 1.在eclipse或者myeclipse 打包时 勾选 ADD DIRECTOR ...
- Webpack - CommonJs & AMD 模块打包器
Webpack 是一个 CommonJs & AMD 模块打包器.可以把你的 JavaScript 代码分离为多个包,在需要的时候进行加载,支持预处理文件,例如 json, jade, cof ...
- Maven之多模块打包成一个jar包及assembly
一.多模块打包 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- 【spring cloud】【IDEA】【Maven】spring cloud多模块打包,打包的jar包只有几k,jar包无法运行,运行报错:no main manifest attribute, in /ms-eureka.jar
======================================================================================== 引申:maven打包多 ...
随机推荐
- Implicit Animations 默认动画 读书笔记
Implicit Animations 默认动画 读书笔记 Do what I mean, not what I say. Edna Krabappel, The Simpsons Part I ...
- C# 移动开发(Xamarin.Form) Plugin.BLE 蓝牙连接
随着Xamarin.Form项目接近尾声,仔细一算才发现过来大半年时间了. 期间除了刚开始有闲情写写,现在总算有空来总结一下了. 来先说 Plugin.BLE (https://github.com/ ...
- monkeyrunner 简单用例编写
monkeyrunnerfrom com.android.monkeyrunner import MonkeyRunner,MonkeyDevice,MonkeyImagedevice = Monke ...
- 在SAP UI中使用纯JavaScript显示产品主数据的3D模型视图
在Jerry写这篇文章时,通过Google才知道,SAP其实是有自己的3D模型视图显示解决方案的. 故事要从Right Hemisphere说起,这是一家专业的企业级2D/3D模型浏览及转换的软件供应 ...
- python基础一 day2
内容: 3%%s 输出:3%s 后面的全部转义 结果: 如果是因为执行break语句导致循环提前结束,就不会执行else. 单位换算: 编码方式: ascii unicode u ...
- Asp.Net Core 入门(二)——Startup.cs做了什么
上篇介绍了Program.cs中Main做了什么,这篇我们来讨论下Startup.cs它又做了什么呢? 我们新建一个Asp.Net Core Mvc项目,先来开一下Startup的代码 public ...
- Android Studio中删除无效的字符串资源
1.定位到当前项目中的strings.xml文件 1.菜单栏找到"Analyze"->"Run Inspection By Name..."->输入 ...
- Android Studio中出现Gradle's dependency cache may be corrupt错误的解决办法
起因 某次打开AS,提示升级AS,升级后,提示升级gradle,选择升级. 结果在升级gradle时耗时较久,没有耐心,点击停止升级gradle, 还是停在那里,然后关闭AS,还是没反应,启动任务管理 ...
- 如何用纯 CSS 创作一个同心圆弧旋转 loader 特效
效果预览 在线演示 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. https://codepen.io/zhang-ou/pen/OZmXQX 可交互视频教程 此视 ...
- 条款27:尽量少做转型动作(Minimize casting)
NOTE : 1.如果可以,尽量避免转型,特别是在注重效率的代码中避免dynamic_casts. 如果有个设计需要转型动作,试着发展无需转型的替代设计. 2.如果转型是必须要的,试着将它隐藏于某个函 ...