这篇文章是自己在整理webpack相关的东西时候突发奇想,想整理出一套由浅入深的博文以此鞭策自己学习,也希望能够帮助想学习webpack的同学,目前都是入门级别的,大佬请出门右转。
学习完本篇文章,我希望您能够掌握以下几点:
- webpack是什么
- webpack有什么有点
- webpack.config.js配置项中,出口(entry)、入口(output)、插件(plugins)的基本作用和配置方法。
- html-webpack-plugin、 clean-webpack-plugin 插件的作用和使用方法。
什么是webpack统一说明,本文中所用到的npm包管理工具均采用淘宝镜像(cnpm),原因你懂得。
webpack版本基于3.0版本,本文中具体是3.8.1版本。
webpack是一个用以对现代Javascript应用程序模块打包工具,它和gulp、grunt的不同之处在于webpack提供了一整套前端模块化开发的解决法案;webpack把资源作为模块来处理,这里的资源不止于javascript,还包括html、css、图片、字体等等。
webpack的优点- 代码分割(code splitting),在开发过程中,webpack允许我们将代码按照不同职能分割成不同模块进行开发,并且在加载中可以按需加载,减少加载时间。
- 插件化,webpack提供了丰富的插件接口,通过配置不同的插件,可以实现我们想要的效果,非常灵活。
- 装载机制,webpack中,我们可以通过提供的loaders预处理项目文件,包括js、css、html、image等。
- 高性能,webpack使用异步I/O流加载模块,并具有多个缓存级别,在渐进式编译中,速度表现很棒。
- 开发方便,weback提供sourceMap和sourceUrl,方便开发者定位调试,并且通过中间件可以实现项目的热更新,这个在开发中很有作用。
构建项目结构
1、初始化, 新建一个文件夹,取名叫webpackDemo,通过控制台或者git bash定位到当前文件下面,执行命令:
npm init //淘宝镜像用 cnpm init
然后一路enter,初始化后,会在该文件夹下面生成一个package.json文件,然后,再次在命令行内执行:
npm install //淘宝镜像用 cnpm install
2、项目结构搭建, 在webpackDemo文件夹下:
- 新建src目录,用于存放开发相关的资源文件;
- 在src目录下新建js、css、views等不同类型的文件夹,以此存放相对应的开发文件。
- 新建dist目录,用于存放打包后生成的文件;
- 和src目录下一样,新建js、css、views等文件夹,存放打包后的文件(案例中,先新建一个js文件夹,因为我们现在只用js来体验webpack)。
- 新建index.html文件。
- 新建webpack.config.js,这是webpack默认关于打包相关的配置文件。
-
新建.babelrc文件,放置babel相关配置,和webpack.config.js一样,babel的配置文件名称,也是固定的,即:.babelrc
注意: webpack默认会读取webpack.config.js 中的相关配置,如果更换其他名字,webpack默认是找不到配置信息的。(当然我们也可以去指定webpack读取的配置文件,在现阶段,我们暂不考虑);
最终的项目结构如下:
初体验
1、代码编写,打开根目录下的index.html,引入webpack最后编译的的js文件,我么定义js名称叫做bundle.js。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webpack demo</title>
</head>
<body>
<!-- 我们给最终编译出的js叫做bundle.js-->
<script src="./dist/js/bundle.js"></script>
</body>
</html>
2、在src/js文件夹下面,新建app.js,作为webpack编译的入口文件,并添加一个方法,在控制台打印出hello world
// app.js
function Hello() {
console.log('hello world')
}
Hello()
3、接下来,我们打开webpack.config.js,给webapck编译指定规则:
// webpack.config.js
var path = require('path');
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),//指定webpack打包的入口是app.js
output: {
path: path.resolve(__dirname, './dist/js'),//指定打包后js文件放置的位置
filename: 'bundle.js'//指定打包后的js名称,这个就是index.html最终引入的js的名称
}
}
1、配置路径用path.resolve()处理,是为了确保路径是从根目录开始绝对定位到指定位置,webpack3.0要求我们在配置路径相关的时候使用绝对路径;
2、path模块是nodejs内置的处理路径相关的模块。
现在让我们打开命令行,执行webpack编译
//如果还未安装webpack,则先执行安装
cnpm i webpack --save-dev
// 安装完成后执行编译
webpack
编译执行完成后,控制台输出以下则表示执行成功。
此时查看dist/js目录,会发现新增了一个bundle.js的文件,在浏览器中打开index.html,再打开控制台,成功输出hello world。
看到这里,估计有人要打人了,就这玩意有啥用,浪费我青春!我要输出的hello world要你这么麻烦干啥。额!骚年,先放下你手上的砖头,有话好好说。
大名鼎鼎的webpack当然不止这就完了,接下来,让我们一步一步真正开始认识webpack。
webpack配置---生成带hash值的js文件
现在,我们来看一下webpack配置文件中的output选项的相关配置,细心的你也许发现,我们最终生成的的bundle.js是我们设定好的,每次打包后生成的名字是不会改变的,但是在实际项目中,为了确保代码更改前后无冲突以及版本回退等一系列问题,每次打包后的包文件,我们会给他打上一个独一无二的标记,用以区分版本,这又是怎么实现的呢?
实际上,webpack在打包编译的时候,会把不同模块的代码分别指定一个chunkhash值,最后整体打包后的js会生成一个hash值 (需要注意chunkhash和hash是不一样的),我们只需要在output配置项中给filename属性一个填写hash的占位符,这样在每次编译的时候,就会生成带有hash值得js文件:
var path = require('path')
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),
output: {
path: path.resolve(__dirname, './dist/js'),
filename: 'bundle-[hash].js'//[hash]为编译时填写hash的占位符,也可以填写chunkhash等
}
}
再次执行编译,我们会发现,新生成的文件已经带有hash值了:
webpack配置---根据模板动态生成Html
上面我们已经动态生成了带有不同hash值得js了,那么问题又来了,既然每次生成的js文件都不一样,我们如何去加载生成的js呢,要知道,在index.html里面,我们写的是bundle.js啊!
为了解决这个问题,我们就想,如果每次webpack打包编译后自动将生成的js注入到我们的index.html模板中,这样我们就不用在我们的index.html中手动添加bundle.js了,不就解决了这个问题么。
实际上!这种思想正是webpack为我们提供的解决方案-- html-webpack-plugin。
首先,我们通过命令行安装这个插件
cnpm install html-webpack-plugin --save-dev
然后,我们在配置文件里新增对html-webpack-plugin的相关配置
var path = require('path');
//引入html-webpack-plugin模块
var htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),
output: {
path: path.resolve(__dirname, './dist/js'),
filename: 'bundle-[hash].js'
},
//初始化插件
plugins:[
new htmlWebpackPlugin({
template:'index.html',//定义插件读取的模板文件是根目录下的index.html
filename:'index.html'//定义通过模板文件新生成的页面名称
})
]
}
在配置文件中,我们新增了plugins这个配置属性,并初始化html-webpack-plugin插件,现在我们去index.html中删除js的引用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>webpack demo</title>
</head>
<body>
<!-- <script src="./dist/js/bundle.js"></script>-->
</body>
</html>
再次执行webpack命令,编译成功后!再看看我们的dist目录下,果然生成了index.html。
提醒一
html-webpack-plugin插件运行的时候,需要在项目安装webpack,如果是全局安装的webpack,在此处运行会报错:Cannot find module 'webpack/lib/node/NodeTemplatePlugin'。
解决办法就是在本地安装webpack,定位到项目的根目录下执行以下命令即可。
cnpn install webpack
提醒二
细心的你可能又发现,生成的index.html也在dist/js文件夹下面,这和我们想要的结果不一样,因为我们想要在dist文件夹下把html、js以及后面的css都分开来,为了解决这个问题,我们须将配置文件的output选项更改一下:
var path = require('path')
var htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),
output: {
// path: path.resolve(__dirname, './dist/js'),
path: path.resolve(__dirname, './dist'),//将输出的路径定位到dist一级就好,然后再filename配置项中,指定二级目录。
//filename: 'bundle-[hash].js'
filename: 'js/bundle-[hash].js'
},
plugins: [
new htmlWebpackPlugin({
template: 'index.html',
filename:'index.html'
})
]
}
在配置中,我们将output中的path路径指定到dist一级就好,至于生成的js路径,我们就将js放置在filename选项下,配置完成后,我们再次在命令行执行"webpack"命令,最终发现,dist目录下新生成了index.html页面,而js,则依然在js文件夹下生成。
webpack配置---清除dist文件夹下面的重复文件
到目前为止,我们的案例可以动态的生成带有自己hash命名的js文件,但是我们发现文件在一直增加,新生成编译文件之前并没有删除上一次编译的文件,这会让项目原来越大。为了解决这个问题,我们需要再次引入一个插件---clean-webpack-plugin。
老规矩,首先是安装,在命令行执行:
cnpm install clean-webpack-plugin --save-dev
然后在配置文件中引入插件并实例化
var path = require('path');
var htmlWebpackPlugin = require('html-webpack-plugin');
//引入插件模块
var cleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, './src/js/app.js'),
output: {
path: path.resolve(__dirname, './dist'),
filename: 'js/bundle-[hash].js'
},
plugins: [
new htmlWebpackPlugin({
template: 'index.html'
}),
//初始化插件配置项
new cleanWebpackPlugin(
['dist'], //匹配要删除的文件,这里则指定每次对dist文件夹进行清理
{
root: __dirname,//指定插件根目录位置
verbose: true, //开启在控制台输出信息
dry: false //启用删除文件
}
)
]
}
在配置中,我们将引入的clean-webpack-plugin实例化,并设置了要删除文件的目录和一些显示设置,再次在命令行执行"webpack"命令,发现之前的文件被删除了,只剩下最新生成的相关文件。
写在最后
这一节,我们向大家初步介绍了webpack的使用,并且从头开始搭建了一个webpack运行的编译环境,初次体验了一下webpack,当然,webpack的功能远远不止于此,它的最重要的功能loader我们还没开始,目前笔者所展示的这些,只是webpack很小很小的一部分。
再次提醒读者盆友,读完本篇文章您应该了解以下内容:
- webpack是什么
- webpack有什么有点
- webpack.config.js配置项中,出口(entry)、入口(output)、插件(plugins)的作用和基本配置方法。
- html-webpack-plugin、 clean-webpack-plugin 插件的作用和使用方法。
下一节,我们将在此基础上学习webpack的加载器用法,包括babel编译es6、css预处理、autoprefixer用法、css与js文件分割等,欢迎大家提出宝贵意见,一起学习。
这是前端最好的时代,也是前端最坏的时代,前端不止,学习不停,愿各位读者努力向前,早日成为前端高手。
热门评论
可以催更吗?可以催更吗?
可以催更吗?可以催更吗?
写的非常棒!我在入门这里卡死了半天,感谢作者