project
- css
- bootstrap.min.css
- jb.css
- fonts
- 一些bootstrap的字体
- images
- 一些项目用到的图片
- js
- bootstrap.min.js
- jquery.min.js
- jb.js
- index.html
- favicon.ico复制代码
这个是公司要作的一个官方网站。因为项目比较简单,要求是单页的,没有页面跳转,因此只有一个 .html 文件。项目用了比较常规的 bootstrap + jquery 的开发,这个也没啥好说的。考虑到 CDN 的可控性,因此把全部 bootstrap 的资源都下载到了本地进行引用。项目开始时是用了常规的 js 和 css 引用(css 放前面,js 放后面),在开发完成后,发现有时间多余,就考虑用 webpack 对他进行处理一下,以巩固和学习一下 webpack 所用到的知识css
npm init
先初始化一个 package.json 文件来管理咱们 webpack 所依赖的文件包。一路无脑回车便可。复制代码
想要用 webpack ,那么你首先确定要安装 webpack 才能够啊。用如下命令:
npm install webpack --save复制代码
在根目录下新建一个 webpack.config.js 文件,用来对 webpack 进行配置。
当有这个文件后,咱们系能够在命令行中用如下命令来启动配置好的 webpack 了。
webpack --config webpack.config.js复制代码
以上虽然也能够启动配置好的 webpack。可是每次要输这么一串命令好像有点太长了(懒啊)。因此在 package.json 中修改这样一项:
"script": {
+ "start": "webpack --config webpack.config.js",
"test": "echo \"Error: no test specified\" && exit 1"
}复制代码
这样的话咱们就能够在命令行中少敲几个键盘了。直接用如下命令,就等同于上面的命令了:html
npm start复制代码
好了,到这里,初始化工做就作完了,那么开始咱们的 webpack 配置吧node
webpack 建立应用程序全部依赖的关系图(dependency graph)。图的起点被称之为入口起点(entry point)。入口起点告诉 webpack 从哪里开始,并根据依赖关系图肯定须要打包的内容。能够将应用程序的入口起点认为是根上下文(contextual root) 或 app 第一个启动文件jquery
跟其余的 spa 应用不同,这样的普通应用,其全部依赖都来自于 index.html 文件。若是说要有入口文件的话,怎么也应该是 index.html 他自己吧。可是 webpack
基本都是用 .js 文件做为入口文件,用 .html 做为入口文件的...(反正我是没有见到过)。至于这里有啥缘由的话,你们就参考一下这篇文章吧。(其实我也不懂)webpack
因此说,无论怎么样,咱们都须要有个入口文件。git
那就无论怎么样,咱们常常看到的 webpack 的配置都是这样的github
module.exports = {
entry: './index.js'
}复制代码
那么咱们无论三七二十一,先在根目录下新建一个 index.js,而后让他做为咱们的入口文件。web
要知道,对于咱们原来的项目而言,咱们根本就是不须要这么一个 index.js 文件的(没有他,咱们能够活得更好)。可是咱们又不得不建立了这样一个文件。那么问题来了,这么建立出来的文件,里面又该放什么内容呢?咱们总不应救这么建立一个空文件就算了吧。npm
在考虑这个问题的时候,咱们能够先去看下 webpack 官方的那个很经典的图(我很懒,就不放图了,你们本身去网上找吧)。webpack 把左边乱七八糟的 .js .css .png .jpg .sass。。。等等文件所有打包成了静态资源。也就是说,webpack 打包的是除 html 外的全部资源,那么咱们是否是只要把这些资源都放到入口文件中那么就可让 webpack 帮咱们打包了呢?json
可是等等。其余的都没有问题,什么 css 啊,什么 js 啊,都好说,由于用来也不过这么几个,可是图片呢,字体呢?我在项目中用了那么多图片,要所有再在 index.js 里面再写一遍!天呐!这是要命的啊!那么我能不能偷懒下,就只写 css 和 js 呢,其余乱七八糟的我先无论?那就先这么来吧。修改咱们的 index.js 文件,添加如下内容。
require('./css/bootstrap.min.css')
require('./css/jubang.css')
require('./js/jquery.min.js')
require('./js/bootstrap.min.js')
require('./js/jb.js')复制代码
先这样把他看成咱们的入口文件吧
出口文件就很好配置了,将他打包到根目录下的 dist 目录中。嗯 ~ 这很常见!
var path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
}
}复制代码
这个不知道怎么配置,就先看这篇文章吧。
因此说,到这里咱们的 webpack.config.js 就是这样的:
var path = require('path');
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [{
test: /\.css$/,
use: [
'style.loader',
'css-loader'
]
}, {
test: /\.(png|jpg|svg|git)$/,
use: [
'file-loader'
]
}, {
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}]
}
}复制代码
这里咱们用到了三个 loader,须要先安装下
npm install css-loader style-loader file-loader --save复制代码
这三个 loader 的做用你们仍是本身去网上查找吧
配置到这里,咱们能够先来打包一下,有问题再改嘛!
命令行切换到项目目录下,执行如下命令:
npm start
打包结束后,项目的目录结构
project
- css
- dist
- fonts
- images
- js
- node-modules
- favicon.ico
- index.html
- index.js
- package.json
- webpack.config.js
咱们能够看到,项目根目录下面多出来一个 dist 的目录。没错,这个就是咱们 webpack 打包后文件生成的目录,至于为何会是 dist 目录,那是由于你在 webpack.config.js 的 output 中设置的 path。
如今咱们来查看下 webpack 打包出了什么东西
- dist
- xxxx.jpg
- xxxx.woff2
- xxxx.jpg
- xxxx.svg
- bundle.js
- xxxx.ttf
- xxxx.eot
- xxxx.woff复制代码
注:xxxx表明一串数字和字母的组合,为了表示方便就这么写了
打包文件中生成了一个 .js 文件,两个 .jpg 文件,四个字体文件(.woff二、.ttf、.eot、.woff),和一个 .svg 文件
咱们来看下这是个类型的文件都来自哪里吧复制代码
bundle.js 是咱们根据咱们入口文件,将咱们在入口文件中全部的依赖资源都打包进去生成的。这个也是咱们最主要要关注的文件。
两个 .jpg 文件是从哪里来的呢?查看了两张图片以后,其实咱们会知道,这两个图片都是在咱们本身写的 jb.css
中用来做为 background-image
引入的。咱们说了,webpack 会根据入口文做为起点,并根据依赖关系图来进行打包的。换句话说,咱们在入口文件中依赖了 jb.css
,而 jb.css
依赖了两张 .jpg 图片,因此 webpack 根据依赖分析,将这两张图片也都一块儿打包进来了。
四个字体文件的来源就须要咱们对 bootstrap 有必定了解了。若是熟悉 bootstrap 的同窗确定会知道,在 bootstrap 的依赖里面,他正是依赖了这些字体,也就是说这些字体文件是从 bootstrap.min.css 文件中被打包进来的。其实我在作这个项目的时候,把 bootstrap 的源码弄到本地的时候,会发现里面有一个 fonts 的文件夹,也就是咱们项目根目录下的 fonts 文件夹,这里会有四个一样文件结尾的字体文件和一个 .svg 结尾的 svg 文件。而这五个文件不就是咱们这里多出来的五个文件嘛
若是还不放心的话,咱们能够再作个验证。修改 webpack.config.js 文件
{
test: /\.(png|jpg|svg|git)$/,
use: [
- 'file-loader'
+ 'file-loader?name=[hash:8].[name].[ext]'
]
}, {
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
- 'file-loader'
+ 'file-loader?name=[hash:8].[name].[ext]'
]
}复制代码
咱们把图片和字体文件,在 file-loader 处理后让他的名字就变成 ’8位hash值-原文件名-后缀名‘的格式,那么咱们就能够比对这几个文件的来源了。
从新打包后(你得先删除原来的 dist 文件夹),咱们就能够发现咱们的猜想是正确的!
虽然咱们的第一次打包成功了,可是仍是留下了几个问题没有解决:第一,个人 js、css、字体、图片等资源都被打包进了 dist 目录,可是做为咱们的项目最主要的 index.html 文件呢?没有这个文件,咱们打包出来的东西还有什么意义呢!。第二,个人 images 文件夹里有那么多图片,你这个 webpack 打包后为何就只有两张图片了,其余的呢?
那么接下来让咱们急需解决。
要解决第一个问题,咱们须要用到 html-webpack-plugin 插件。这个插件的具体说明能够查看这里。这个插件的做用是能够将 html 文件打包,并自动添加对打包后的 output 文件的引用。具体如何使用,请先安装:
npm install html-webpack-plugin --save复制代码
修改配置文件:
var path = require('path');
+ var HtmlWebpackPlugin = require('html-webpack-plugin');
在 module 后面加
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
})
]复制代码
咱们在配置文件中引入了一个插件,并向 HtmlWebpackPlugin 构造函数传递了一个对象参数,在这个对象参数中,咱们指明了一个 template 字段,表面咱们要打包的 html 的文件源。而后咱们从新打包,再查看咱们的目录就能够发现 dist 目录下多出了一个 index.html。因为这个项目自己就是一个简单的不依赖任何环境的项目,因此若是正常的话咱们直接打开 index.html 页面就能在浏览器里正常显示了。虽然不知道会怎么样,可是咱们仍是打开来试试吧。
当咱们打开 index.html 在浏览器中显示的时候,咱们发现浏览器中好多图片都不见了。细想咱们的项目代码,发现除了在 jb.css 中的背景图被正确显示之外,其余的定义在 img 标签中的图片没有一张是显示出来的。
因此虽然这个文件配置还有点问题没解决,那么咱们先来解决 html 中的 img 问题吧,也就是咱们上面提到的第二个问题。
要解决第二个问题(也就是 html 中的 img 问题),咱们须要用到 html-whithimg-loader,具体关于这个怎么用能够查看这里。
修改配置文件,直接在 rules 中再添加一条配置规则
{
test: /\.(html|htm)$/,
use: [
'html-withimg-loader'
]
}复制代码
这条配置规则代表,全部要处理的 html 文件首先会通过 html-withimg-loader 这个 loader 处理。就是这么简单能将咱们第二个问题解决吗?试试看吧,事件是检验真理的惟一标准。
从新打包,再查看 dist 目录,这一查看没关系,发现 dist 目录下多了好多图片文件,密密麻麻,乱七八糟的,这些该不会就是咱们 html 中的图片吧。按住本身的强迫症,先找到 index.html (咱们最关心的仍是他嘛),打开后再浏览器查看效果。发现果真,咱们的图片都已经在了,并且样式也差很少对了。可是这么乱七八糟的 dist 目录,怎么会是咱们这种强迫症患者所想要的结果呢!咱们想要的是图片都放在图片文件夹下,字体都放在字体文件夹下,其余的比较少的就先让他在外面呆着吧。说干就干,咱们来调整一下咱们的配置文件
{
test: /\.(png|jpg|svg|git)$/,
use: [
- 'file-loader?name=[hash:8].[name].[ext]'
+ 'file-loader?name=images/[hash:8].[name].[ext]'
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
- 'file-loader?name=[hash:8].[name].[ext]'
+ 'file-loader?name=fonts/[hash:8].[name].[ext]'
]
} 复制代码
还有一个问题我已经忍了好久了,每次打包前,咱们都须要手动先去删除上次打包留下来的 dist 目录,这个就烦了,虽然只是一个 delete 的事情,可是作多了也烦啊!咱们想能不能让 webpack 自动帮咱们作了这件事,让咱们不须要手动去删除。还好 webpack 够智能,总能知足你提出来的各类无理取闹。不过咱们先要装一个插件:
npm install clean-webpack-plugin --save复制代码
而后再配置文件中添加对这插件的引用
var HtmlWebpackPlugin = require('html-webpack-plugin');
+ var CleanWebpackPlugin = require('clean-webpack-plugin');复制代码
在 plugins 中添加对这个插件的使用
new CleanWebpackPlugin(['dist'])复制代码
这样咱们就能不用手动删除 dist 文件夹了。
从新打包下试试吧!
打包完后咱们在查看 dist 目录就瞬间感受清爽多了有木有!
- dist
- fonts
- 一些字体文件
- images
- 一些图片文件
- bundle.js
- index.html复制代码
将打包后的项目再次在浏览器中查看,并查看控制台会发现,控制台报了一堆错误。其中有几个是对一些 css、js 文件引用的错误。由于咱们把须要用的 css、js 都打包进了 bundle.js 中了。而咱们原来的项目是经过静态资源引用的方式一个个导入 html 文件中的。因此,当咱们 webpack 打包成功后,就不须要对这些资源进行引用了,咱们只须要对 bundle.js(咱们打包后的文件)进行引用就能够了,所幸的是,打包后的文件 webpack 已经自动帮咱们引用了。因此直接在原来项目中的 index.html 中干掉那些 css、js 就能够了。而后从新打包后就没有这些资源找不到的乱七八糟的错误了。
可是,有一个小问题就是关于咱们的 .ico 文件。这是咱们网站的图标文件。他的引用错误该如何解决呢?咱们能够在生成 html 的时候,将这个问题先给解决了。修改配置文件
new HtmlWebpackPlugin({
template: './index.html',
+ favicon: path.resolve(__dirname, './favicon.ico')
})复制代码
这样的话咱们的图标文件也就有了。
虽然一些乱七八糟的引用错误解决了,可是控制台留下了一个让咱们很是头疼的问题:jquery 的引用问题:
Uncaught Error: Bootstrap's JavaScript requires jQuery复制代码
这里咱们须要用到 expose-loader 这个东西,关于他,能够查看这里,废话很少说:
npm install expose-loader --save复制代码
在 module 的 rules 中再添加一个 loader
{
test: require.resolve('./js/jquery.min.js'), // 引入 jquery
use: [{
loader: 'expose-loader',
options: '$'
}, {
loader: 'expose-loader',
options: 'jQuery'
}]
}复制代码
固然,网上或许有其余方法关于引入 jquery 的,这里只是说一种。而后再打包咱们的页面就没有问题了:各类资源都有了,js 写的效果也出现了。
虽然网站看上去没啥问题了,可是细心的同窗确定会发现:当咱们打开网站的时候,他会先出现一个没有样式的页面,而后一闪而逝,最后才出现咱们预期的样子。这是为何呢?
缘由很好理解,由于咱们把 css 和 js 都打包进了同一个 bundle.js 里面了。可是,这个 bundle.js 是在页面最后面才加载进来的。也就是说,咱们的样式被放在了页面的底部被加载。这彻底不符合咱们的预期啊。咱们但愿的是样式在 head 中加载,而 js 脚本才放在页面底部加载。因此咱们就不能把 css 和 js 一块儿打包进 bundle.js 中了。
详细资料看这里
npm install extract-text-webpack-plugin --save复制代码
增长 require
var ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');复制代码
修改 css rules
{
test: /\.css$/,
use: ExtractTextWebpackPlugin.extract[{
fallback: 'style-loader',
use: 'css-loader'
}]
}复制代码
增长 plugin
new ExtractTextWebpackPlugin('style.css')复制代码
打包,而后咱们会发现 dist 中多了一个 style.css,而后再 index.html 的 head 中的多了对这个 css 的引用
增长 plugin
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})复制代码
new HtmlWebpackPlugin({
template: './index.html',
favicon: path.resolve(__dirname, './favicon.ico'),
minify: {
removeAttributeQuotes: true,
removeComments: true,
removeEmptyAttribute: true,
collapseWhitespace: true
}
}),复制代码
{
test: /\.(jpg|png|gif|svg)$/,
- use: 'file-loader?name=images/[hash:8].[name].[ext]'
+ use: 'url-loader?limit=8192&name=images/[hash:8].[name].[ext]'
}复制代码
暂时就先那么多吧,没时间写了,之后再说。第一次发文,求轻虐。