关于Webpack详述系列文章 (第一篇)
WebPack官网地址(https://webpack-china.org/)
1. 什么是WebPack
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
构建就是把源代码转换成发布到线上的可执行 JavaScrip、CSS、HTML 代码,包括如下内容。
- 代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等。
- 文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。
- 代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。
- 模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。
- 自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。
- 代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。
- 自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。
构建其实是工程化、自动化思想在前端开发中的体现,把一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程。 构建给前端开发注入了更大的活力,解放了我们的生产力。
2. 初始化项目
mkdir webpack-start
cd webpack-start
npm init
3. 快速上手
3.1 webpack核心概念
- Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。
- Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的 Entry 开始递归找出所有依赖的模块。
- Chunk:代码块,一个 Chunk 由多个模块组合而成,用于代码合并与分割。
- Loader:模块转换器,用于把模块原内容按照需求转换成新内容。
- Plugin:扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。
- Output:输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。
==> Webpack 启动后会从Entry
里配置的Module
开始递归解析 Entry 依赖的所有 Module。 每找到一个 Module, 就会根据配置的Loader
去找出对应的转换规则,对 Module 进行转换后,再解析出当前 Module 依赖的 Module。 这些模块会以 Entry 为单位进行分组,一个 Entry 和其所有依赖的 Module 被分到一个组也就是一个 Chunk
。最后 Webpack 会把所有 Chunk 转换成文件输出。 在整个流程中 Webpack 会在恰当的时机执行 Plugin 里定义的逻辑。
3.2 配置webpack
npm install webpack webpack-cli -D
- 创建src
- 创建dist
- 创建index.html
- 配置文件webpack.config.js
- 配置文件webpack.config.js
- entry:配置入口文件的地址
- output:配置出口文件的地址
- module:配置模块,主要用来配置不同文件的加载器
- plugins:配置插件
- devServer:配置开发服务器
4. 配置开发服务器
npm i webpack-dev-server –D
- contentBase 配置开发服务运行时的文件根目录
- host:开发服务器监听的主机地址
- compress 开发服务器是否启动gzip等压缩
- port:开发服务器监听的端口
devServer:{
contentBase:path.resolve(__dirname,'dist'),
host:'localhost',
compress:true,
port:8080
}
"scripts": {
"build": "webpack --mode development",
"dev": "webpack-dev-server --open --mode development "
}
5. 支持加载css文件
5.1 什么是Loader
通过使用不同的Loader,Webpack可以要把不同的文件都转成JS文件,比如CSS、ES6/7、JSX等
- test:匹配处理文件的扩展名的正则表达式
- use:loader名称,就是你要使用模块的名称
- include/exclude:手动指定必须处理的文件夹或屏蔽不需要处理的文件夹
- query:为loaders提供额外的设置选项
loader三种写法
- use
- loader
- use+loader
5.2 css-loader
npm i style-loader css-loader -D
配置加载器
module: {
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader'],
include:path.join(__dirname,'./src'),
exclude:/node_modules/
}
]
},
6. 自动产出html
我们希望自动能产出HTML文件,并在里面引入产出后的资源
npm i html-webpack-plugin -D
- minify 是对html文件进行压缩,removeAttrubuteQuotes是去掉属性的双引号
- hash 引入产出资源的时候加上哈希避免缓存
- template 模版路径
plugins: [
new HtmlWebpackPlugin({
minify: {
removeAttributeQuotes:true
},
hash: true,
template: './src/index.html',
filename:'index.html'
})]
7. 支持图片
7.1 手动添加图片
npm i file-loader url-loader -D
- file-loader 解决CSS等文件中的引入图片路径问题
- url-loader 当图片较小的时候会把图片BASE64编码,大于limit参数的时候还是使用file-loader 进行拷贝
let logo=require('./images/logo.png');
let img=new Image();
img.src=logo;
document.body.appendChild(img);
{
test:/\.(jpg|png|gif|svg)$/,
use:'url-loader',
include:path.join(__dirname,'./src'),
exclude:/node_modules/
}
7.2 在CSS中引入图片
还可以在CSS文件中引入图片
.img-bg{
background: url(./images/logo.png);
width:173px;
height:66px;
}
8. 分离CSS
因为CSS的下载和JS可以并行,当一个HTML文件很大的时候,我们可以把CSS单独提取出来加载
npm install --save-dev extract-text-webpack-plugin@next
{
test:/\.css$/,
use: ExtractTextWebpackPlugin.extract({
use:'css-loader'
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
}, plugins: [
new ExtractTextWebpackPlugin('css/index.css'),
处理图片路径问题
const PUBLIC_PATH='/'; output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath:PUBLIC_PATH
},
指定打包后的图片位置
use: [
{
loader: 'url-loader',
options: {
limit: 1024,
outputPath:'images/'
}
}
],
在HTML中使用图片
npm i html-withimg-loader -D
<div class="img-container "><img src="./images/logo.png" alt="logo.png"></div>
{
test:/\.(html|html)$/,
use:'html-withimg-loader',
include:path.join(__dirname,'./src'),
exclude:/node_modules/
}
9. 编译less 和 sass
npm i less less-loader -D
npm i node-saas sass-loader -D
@color:orange;
.less-container{
border:1px solid @color;
} $color:green;
.sass-container{
border:1px solid $color;
}
const cssExtract=new ExtractTextWebpackPlugin('css.css');
const lessExtract=new ExtractTextWebpackPlugin('less.css');
const sassExtract=new ExtractTextWebpackPlugin('sass.css'); {
test:/\.less$/,
use: lessExtract.extract({
use:['css-loader','less-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
{
test:/\.scss$/,
use: sassExtract.extract({
use:['css-loader','sass-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
10. 处理CSS3属性前缀
为了浏览器的兼容性,有时候我们必须加入-webkit,-ms,-o,-moz这些前缀
- Trident内核:主要代表为IE浏览器, 前缀为-ms
- Gecko内核:主要代表为Firefox, 前缀为-moz
- Presto内核:主要代表为Opera, 前缀为-o
- Webkit内核:产要代表为Chrome和Safari, 前缀为-webkit
npm i postcss-loader autoprefixer -D
postcss.config.js
module.exports={
plugins:[require('autoprefixer')]
}
.circle {
transform: translateX(100px);
}
{
test:/\.css$/,
use: cssExtract.extract({
use:['css-loader','postcss-loader']
}),
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
11. 转义ES6/ES7/JSX
Babel其实是一个编译JavaScript的平台,可以把ES6/ES7,React的JSX转义为ES5
npm i babel-core babel-loader babel-preset-env babel-preset-stage-0 babel-preset-react -D
{
test:/\.jsx?$/,
use: {
loader: 'babel-loader',
options: {
presets: ["env","stage-0","react"]
}
},
include:path.join(__dirname,'./src'),
exclude:/node_modules/
},
12. 如何调试打包后的代码
webapck通过配置可以自动给我们source maps
文件,map
文件是一种对应编译文件和源文件的方法
- source-map 把映射文件生成到单独的文件,最完整最慢
- cheap-module-source-map 在一个单独的文件中产生一个不带列映射的Map
- eval-source-map 使用eval打包源文件模块,在同一个文件中生成完整sourcemap
- cheap-module-eval-source-map sourcemap和打包后的JS同行显示,没有映射列
devtool:'eval-source-map'
13.打包第三方类库
13.1 直接引入
import _ from 'lodash';
alert(_.join(['a','b','c'],'@'));
13.2 插件引入
new webpack.ProvidePlugin({
_:'lodash'
})
14. watch
当代码发生修改后可以自动重新编译
new webpack.BannerPlugin('珠峰培训'), watch: true,
watchOptions: {
ignored: /node_modules/, //忽略不用监听变更的目录
aggregateTimeout: 500, //防止重复保存频繁重新编译,500毫米内重复保存不打包
poll:1000 //每秒询问的文件变更的次数
},
15. 拷贝静态文件
有时项目中没有引用的文件也需要打包到目标目录
npm i copy-webpack-plugin -D
new CopyWebpackPlugin([{
from: path.join(__dirname,'public'),//静态资源目录源地址
to:'./public' //目标地址,相对于output的path目录
}]),
16. 打包前先清空输出目录
npm i clean-webpack-plugin -D
new cleanWebpaclPlugin(path.join(__dirname,'dist'))
17. 压缩JS
压缩JS可以让输出的JS文件体积更小、加载更快、流量更省,还有混淆代码的加密功能
npm i uglifyjs-webpack-plugin -D
plugins: [
new UglifyjsWebpackPlugin(), ]
18. 压缩CSS
webpack可以消除未使用的CSS,比如bootstrap中那些未使用的样式
npm i -D purifycss-webpack purify-css
npm i bootstrap -S
{
test:/\.css$/,
use: cssExtract.extract({
use: [{
loader: 'css-loader',
options:{minimize:true}
},'postcss-loader']
}),
},
new PurifyCSSPlugin({
//purifycss根据这个路径配置遍历你的HTML文件,查找你使用的CSS
paths:glob.sync(path.join(__dirname,'src/*.html'))
}),
19. 服务器代理
如果你有单独的后端开发服务器 API,并且希望在同域名下发送 API 请求 ,那么代理某些 URL 会很有用。
//请求到 /api/users 现在会被代理到请求 http://localhost:9000/api/users。
proxy: {
"/api": "http://localhost:9000",
}
proxy: {
"/api": {
target: "http://localhost:9000",
pathRewrite: {"^/api":""}
}
}
20. resolve解析
20.1 extensions
指定extension之后可以不用在require或是import的时候加文件扩展名,会依次尝试添加扩展名进行匹配
resolve: {
//自动补全后缀,注意第一个必须是空字符串,后缀一定以点开头
extensions: ["",".js",".css",".json"],
},
20.2 alias
配置别名可以加快webpack查找模块的速度
- 每当引入jquery模块的时候,它会直接引入jqueryPath,而不需要从node_modules文件夹中按模块的查找规则查找
- 不需要webpack去解析jquery.js文件
const bootstrap=path.join(__dirname,'node_modules/bootstrap/dist/css/bootstrap.css')
resolve: {
alias: {
'bootstrap': bootstrap
}
},
21. 区分环境变量
许多 library 将通过与 process.env.NODE_ENV 环境变量关联,以决定 library 中应该引用哪些内容。例如,当不处于生产环境中时,某些 library 为了使调试变得容易,可能会添加额外的日志记录(log)和测试(test)。其实,当使用 process.env.NODE_ENV === 'production' 时,一些 library 可能针对具体用户的环境进行代码优化,从而删除或添加一些重要代码。我们可以使用 webpack 内置的 DefinePlugin 为所有的依赖定义这个变量:
npm install cross-env -D
"scripts": {
"build": "cross-env NODE_ENV=production webpack --mode development",
"dev": "webpack-dev-server --open --mode development "
},
plugins: [
new webpack.DefinePlugin({
NODE_ENV:JSON.stringify(process.env.NODE_ENV)
}),
if (process.env.NODE_ENV == 'development') {
console.log('这是开发环境');
} else {
console.log('这是生产环境');
}
22. 暴露全局对象
require("expose-loader?libraryName!./file.js");
require("expose-loader?_!loadash"); let _=require('expose-loader?_!lodash');
{
test: /^lodash$/,
loader: "expose?_"
}
setTimeout(function(){
console.log(window._);
});
23. 多入口
有时候我们的页面可以不止一个HTML页面,会有多个页面,所以就需要多入口
entry: {
index: './src/index.js',
main:'./src/main.js'
},
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[hash].js',
publicPath:PUBLIC_PATH
},
new HtmlWebpackPlugin({
minify: {
removeAttributeQuotes:true
},
hash: true,
template: './src/index.html',
chunks:['index'],
filename:'index.html'
}),
new HtmlWebpackPlugin({
minify: {
removeAttributeQuotes:true
},
hash: true,
chunks:['main'],
template: './src/main.html',
filename:'main.html'
})],
24. externals
如果我们想引用一个库,但是又不想让webpack打包,并且又不影响我们在程序中以CMD、AMD或者window/global全局等方式进行使用,那就可以通过配置externals
const $ = require("jquery");
const $ = window.jQuery;
externals: {
jquery: "jQuery"//如果要在浏览器中运行,那么不用添加什么前缀,默认设置就是global
},
关于Webpack详述系列文章 (第一篇)的更多相关文章
- 关于Webpack详述系列文章 (第四篇)
1. webpack基本概念 Entry:入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入.Module:模块,在 Webpack 里一切皆模块,一个模块对应着一个文件.We ...
- 关于Webpack详述系列文章 (第三篇)
1. 类图 1. 模块 Module是webpack中最核心的类,要加载定的一切和依赖都是Module. 它有很多子类 RawModule NormalModule MultiModule Conte ...
- 关于Webpack详述系列文章 (第二篇)
1.缩小文件搜索范围 1.1.1 include & exclude module:{ rules:[ { test:/\.js$/, use:['babel-loader?cacheDire ...
- spring cloud系列教程第一篇-介绍
spring cloud系列教程第一篇-介绍 前言: 现在Java招聘中最常见的是会微服务开发,微服务已经在国内火了几年了,而且也成了趋势了.那么,微服务只是指spring boot吗?当然不是了,微 ...
- 实例讲解webpack的基本使用第一篇
更新文章不容易,尤其是更新高质量的文章更加不易,因此为了节约时间,闲话就不多说了.关于webpack的介绍,webpack是用来干嘛的,这些基础概念性的东西,就不在此赘述,下面直接开始正题. webp ...
- 微信小程序 | 49,小程序入门集锦系列文章20篇
以下20篇文章,都是关于微信小程序的文章,以入门常见问题为主.如发现谬误,请与笔者联系. [小程序入门集锦]1,微信小程序在哪里打开 [小程序入门集锦]2,小程序商店 [小程序入门集锦]3,微信小程序 ...
- Android异步处理系列文章四篇之三
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...
- Android异步处理系列文章四篇之二 使用AsyncTask异步更新UI界面
Android异步处理一:使用Thread+Handler实现非UI线程更新UI界面Android异步处理二:使用AsyncTask异步更新UI界面Android异步处理三:Handler+Loope ...
- Python高级网络编程系列之第一篇
在上一篇中我们简单的说了一下Python中网络编程的基础知识(相关API就不解释了),其中还有什么细节的知识点没有进行说明,如什么是TCP/IP协议有几种状态,什么是TCP三次握手,什么是TCP四次握 ...
随机推荐
- Visual Studio2008 和2010 执行程序出现的黑框马上消失解决方法
1 在程序最后加 system("PAUSE"); 要注意包括头文件#include"stdlib.h" //system须要调用这个 ...
- oracle 10g/11g RAC 启停归档模式
oracle 10g rac 启停归档模式 假设Oracle数据库执行在归档模式,当进行数据库维护时,可能须要暂停数据库的归档,在完毕维护后,再又一次启动归档模式. 通过下面步骤能够从归档 ...
- JNI学习积累之二 ---- 数据类型映射、域描述符说明
本文原创,转载请注明出处:http://blog.csdn.NET/qinjuning 在Java存在两种数据类型: 基本类型 和 引用类型 ,大家都懂的 . 在JNI的世界里也存在类似的数据类型,与 ...
- OPENCV(1)
VS 程序的默认路径是源码所在路径(所以图片应该放在此处),而不是Debug路径 OpenCV 模块结构: core--定义了基本数据结构,包括最重要的Mat和一些其他的模块 imgproc--该 ...
- IPv4私有IP地址有哪些!
私有IP地址是一段保留的IP地址.只是使用在局域网中,在Internet上是不使用的. 私有IP地址的范围有: 私网地址分有三类, A类中,第一段为10的都为私网地址,B类中,以172.16--172 ...
- UVC和V4L2的关系(转载)
UVC是一种usb视频设备驱动.用来支持usb视频设备,凡是usb接口的摄像头都能够支持 V4L2是Linux下的视频采集框架.用来统一接口,向应用层提供API UVC: USB video clas ...
- Python中import和from的一些事。。。
摘自python学习手册, 用于记录. 客户端可以执行import或from语句.如果模块还没有加载,这两个语句会去搜索.编译以及执行模块文件程序.主要差别在于,import会读取整个模块,所以必须进 ...
- javaWeb自己定义可排序过滤器注解,解决Servlet3.0下@WebFilter注解无法排序问题
com.lwl.anno 凝视类型 @WebFilterSort 须要用的jar包 http://download.csdn.net/detail/u013202238/9431110 用该注解注冊的 ...
- hdu1078 FatMouse and Cheese(记忆化搜索)
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:pid=1078" target="_blank">http://acm. ...
- Image-Loader LruMemoryCache
这段时间在研究Universal-Image-Loader 这个图片处理开源框架,这里主要分析一下它的LRU(Least Resently Used,最近最少使用算法)内存缓存的实现. 在UIL它提供 ...