webpack V3.X 入门指南(完)
webpack
前言
这篇文章是我在学习过程中对自己的一个记录和总结,也希望可以帮助到和我当初同样对webpack有困惑的小伙伴
我在自学webpack时也参考了很多大神的文章,参考的帖子太多就不一一谢过了,再次感谢各位大神的帮助
文章中的每个例子,我都是亲自测试过的,如果哪个地方出现笔误等问题还请大家批评,我会及时改正
本文使用的webpack版本是V3.8.1
第一章 webpack能做什么
简介
现如今前端主流的三种框架VueJs、ReactJs、AngularJs都推荐与webpack共同使用,所以不管你是哪种技术路线都不得不去学习了解webpack。那么webpack到底是何方神圣?
官方说法是webpack是一个模块打包机,我个人理解是它可以把我们在开发环境下的代码以及依赖文件等打包成在生产环境下可以直接使用的文件。也可以把一些浏览器不能直接运行的文件进行转化,比如是css、less、scss等。同时webpack也可以对代码进行优化,比如压缩、合并、文件缓存等等。在项目中我们只需要把相应的配置文件配置好,那么接下来的工作就都可以交给webpack这个全能大神去完成了。
官方网站
中文:https://doc.webpack-china.org/
Github:https://github.com/webpack/we...
第二章 webpack安装
全局安装
npm install –g webpack
查看版本号
webpack -v
注意:全局安装并不推荐,因为全局安装以后版本就固定了,比如当前你全局安装了V3.8.1这个版本的webpack,如果你需要运行一个比较早期版本的项目,比如webpack2的项目,就会有问题。另外,如果当前项目你使用V3.8.1版本写的,如果有一天webpack的版本升级了,比如升级到了V4.X,那么你之前的项目很有可能就跑不起来了。所以并不建议全局安装,而是建议项目安装。
项目安装
进入项目所在目录:
npm init npm install --save-dev webpack
注意:
npm init 命令的目的是生成
package.json
文件mac需要在命令前面加:
sudo
如果npm命令安装慢,可以使用
cnpm(https://npm.taobao.org/)
或者是yarn(https://yarnpkg.com/zh-Hans/
项目安装的话,
webpack -v
命令是查看不了版本号的,因为项目安装时webpack
是被安装到node_modules
里面的
第三章 开发环境与生产环境
初学者会有一个疑问,为什么有的时候安装依赖包的时候是--save-dev
,而有的时候是--save
,这两个有什么区别呢?什么时候包含dev
呢?
这就需要搞清楚一个概念:开发模式
和 生产模式
。
开发模式 --save-dev
项目在开发编码过程中还未上线使用就属于开发模式,该模式下代码不需要压缩、合并等。比如编写可以使用sass进行css预处理,使用ES6的语法来编写js代码。在开发模式下依赖的包安装的时候就需要使用--save-dev
,dev
表示开发的意思,使用--save-dev
安装的依赖包,会安装在package.json
的devDependencies
中,这些依赖包只在开发时候会使用到,在上线生成环境下就不需要了。
生产模式 --save
项目已经开发测试完成需要打包上线进行运营了,这时候就属于生产模式,改模式下的文件需要是最终浏览器可以直接解析的文件,不能再用如.scss
、.vue
、.jsx
等这样的文件了。在生产模式下依赖的包安装的时候就需要使用--save
,使用--save
安装的依赖包,会安装在package.json
的dependencies
中,这些依赖包是最终在上线时候使用到的,比如jquery.js
、vue.js
等。
大家在开发过程中安装每个依赖包的时候,都一定先考虑这个包是只有开发模式下能用到,还是在生产模式下也需要用到,其实大家按照这个思路把下面的文章都看完,应该就可以对
--save-dev
和--save
有一个自己的理解了
第四章 Hello World
不管学习什么语言或工具,Hello World都是必不可少的。
目录结构
src:存放开发环境下的文件,也就是我们平时写的代码都在这里面
dist:存放生产环境下的文件,也就是打包后的文件,项目上线时把
dist
文件夹中的内容拷贝到服务器上就可以使用了node_modules:是自动生成的存放依赖包的文件夹,使用
npm install
命令安装依赖包
在src目录下,新建文件helloworld.js
alert('Hello World!');
webpack.config.js
在src同级目录下,新建文件webpack.config.js
const path = require('path'); module.exports = { //入口文件的配置项 entry: { hello: './src/helloworld.js' }, //出口文件的配置项 output: { path: path.resolve(__dirname, 'dist'), //[name]对应的是entry里面的属性名,当然也可以指定打包后的文件名称 filename: '[name].js' }, //模块,loader都是在这里面配置 module: {}, //插件 plugins: [] };
在webpack中,最重要的就是webpack.config.js文件,几乎所有的配置项都需要在该文件中配置,该文件中最重要的四项分别是:entry(入口)、ouput(出口)、module(模块)、plugins(插件)。
path.resolve(__dirname, 'dist')是取到当前项目的路径下的dist文件夹,是nodejs的语法。
配置好webpack.config.js
文件后,需要在package.json
中配置scripts
,之所以要配置build
,是因为我们的webpack
并不是全局安装的,而是项目安装的,项目安装的话webpack命令就被安装到了node_modules
下面,所以需要配置才能找到该命令。
"scripts": { "build": "webpack --watch" }
执行命令进行打包:
npm run build
打包成功后,就会在dist
文件夹下,自动生成hello.js
文件。
--watch
可以实时监控改变自动打包
watchOptions: { // 检测时间间隔 poll : 1000, // 防止重复导报,500毫秒以内不在重复打包 aggregeateTimeout: 500, // 忽略的文件夹 ignored: /node_modules/ }
第五章 webpack-dev-server
在webpack里可以配置服务,这样的好处是页面不再使用本地协议打开,而是通过服务打开,这样ajax等就可以正常使用了。同时,当我们修改代码并保存时,可以实时更新到页面上,提高开发效率。
在webpack.config.js文件中,在与entry等同级配置下增加devServer
配置
const path = require('path'); module.exports = { //入口文件的配置项 entry: { hello: './src/helloworld.js' }, //出口文件的配置项 output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, //模块,loader都是在这里面配置 module: {}, //插件 plugins: [], devServer: { //设置目录结构 contentBase: path.resolve(__dirname, 'dist'), //服务器的IP地址 host: '127.0.0.1', //服务端压缩是否开启 compress: true, //服务端口号 port: 8081 } };
在package.json
文件中进行配置
"scripts": { "build": "webpack --watch", "server": "webpack-dev-server" }
这样的话就可以通过npm run server
来开启服务了,在地址栏里就可以根据devServer
里的配置信息来访问你的网站了,比如按照我的配置的话我需要在浏览器地址栏输入:http://127.0.0.1:8081
来访问我的网站。
第六章 HTML文件打包
在项目中,我们需要把src
目录下的html文件进行打包,打包到dist
目录下,这里我以单页面为例。在src
目录下,创建index.html
文件
需要安装html-webpack-plugin
插件
npm install --save-dev html-webpack-plugin
在webpack.config.js
中引入安装的插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path'); module.exports = { //入口文件的配置项 entry: { hello: './src/helloworld.js' }, //出口文件的配置项 output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js' }, //模块,loader都是在这里面配置 module: {}, //插件 plugins: [ new HtmlWebpackPlugin({ minify: { //移除html中的引号 removeAttributeQuotes: true, //去掉html文件中的回车和空格 collapseWhitespace: true }, hash: true, template: './src/index.html' }) ], devServer: { //设置目录结构 contentBase: path.resolve(__dirname, 'dist'), //服务器的IP地址 host: '127.0.0.1', //服务端压缩是否开启 compress: true, //服务端口号 port: 8081 } };
注意:所有的plugins(插件)都需要安装并在webpack.config.js文件中引入,然后才能使用。
第七章 CSS 文件打包
css打包
项目中,css文件需要进行打包,在入口js文件中通过import
引入css文件
import css from './css/index.css'
css文件打包需要依赖两个包
style-loader:用来处理css文件中的url()等,url挂在到js中
css-loader:用来将css插入到页面的style标签 安装style-loader:npm
安装两个依赖包:
install --save-dev style-loader css-loader
在webpack.config.js
文件中进行配置
module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' },{ loader: 'css-loader' } ] } }
注意:这两个包的引入是有先后顺序的,一定要县引入
style-loader
然后再引入css-loader
,因为两个文件有依赖关系。
执行命令进行打包:
npm run build
注意: 这时css文件中的代码会被打包到js里面
css文件分离
项目中大多数时候我们需要把css文件单独分离出来,而不是打包到js文件中,这时就需要依赖插件extract-text-webpack-plugin
,安装插件
npm install --save-dev extract-text-webpack-plugin
在webpack.config.js
文件中引入插件
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module: { rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader"] }) } ] }
在plugins
中引入
plugins: [ new HtmlWebpackPlugin({ minify: { removeAttributeQuotes: true, collapseWhitespace: true }, hash: true, template: './src/index.html' }), new ExtractTextPlugin("css/index.css") ]
css文件会分离出来,但如果css中引用的图片不是base64格式而是独立的图片文件, 这时候就会出现路径问题导致找不到图片地址,需要在output
配置publicPath
来解决,其中IP地址和端口号需要根据自己项目的实际情况来配置
output: { path: path.resolve(__dirname, 'dist'), filename: '[name].js', publicPath: 'http://127.0.0.1:8081/' }
第八章 JS代码压缩
项目上线后,js文件通常都是需要进行压缩的,这样可以减小文件体积加快加载速度,当然webpack
中已经自带了uglifyjs-webpack-plugin
插件来实现js代码压缩功能。
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
在webpack.config.js
文件中的plugins
中增加
plugins: [ new HtmlWebpackPlugin({ minify: { removeAttributeQuotes: true, collapseWhitespace: true }, hash: true, template: './src/index.html' }), new ExtractTextPlugin("css/index.css"), new UglifyJSPlugin() ]
注意:使用
npm run build
命令可以打包成功,js文件也可以进行压缩,但是使用npm run server
开启dev server
是就会报错,原因是当前还处于开发模式中,正常情况下开发模式是不需要进行js文件压缩的,所以会报错。等到真正上线在生产模式下也不可能会使用der server
的。
第九章 图片打包
图片打包分为两节介绍,因为在网页开发中图片引用的方式主要是两种,一种是在css文件
中作为背景图片background-image: url(xx.jpg)
,另一种是在html文件中
使用标签引入<img src="xx.jpg"/>
CSS中引用的图片
需要依赖两个loader
,分别是file-loader
和 url-loader
,当然也一定是需要先安装后使用了
npm install --save-dev file-loader url-loader
在module
中增加对图片的规则
{ // 匹配图片文件后 缀名称。 test: /\.(png|jpg|gif)/, // 指定使用的loader和配置参数 use: [{ loader: 'url-loader', options: { // 把小于5000B的文件打成Base64的格式写入JS,大于这个大小的图片文件会生成单独的图片文件,这个大小具体多少看实际项目要求,单位为B limit: 50000, // 图片输出到dist文件夹中的images文件夹中 outputPath: 'images/' } }] }
注意:在
loader
中我们只配置了url-loader
而没有配置file-loader
,原因是url-loader
封装了file-loader
。当文件大于limit
中限制大小需要生成图片文件时,url-loader
会调用file-loader
进行处理,参数也会直接传给file-loader
HTML中引用的图片
需要依赖于html-withimg-loader
npm install html-withimg-loader --save-dev
在module
中增加对html
文件的规则
{ test: /\.(html|htm)$/i, use: ['html-withimg-loader'] }
第十章 SASS打包
什么是SASS?CSS 预处理器定义了一种新的语言,其基本思想是,用一 种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言 进行编码工作。
通俗的说,“CSS 预处理器用一种专门的编程语言,进行 Web 页面样式设计,然后再编译成正常的 CSS 文件,以供 项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无 需考虑浏览器的兼容性问题”,例如你可以在 CSS 中使用
变量、简单的逻辑程序、函数等等在编程语言中的一些基 本特性,可以让你的 CSS 更加简洁、适应性更强、可读性
更佳,更易于代码的维护等诸多好处。
在开发过程中,使用扩展名为.scss
的文件来编写css样式
,但该文件并不能直接被浏览器解析,所以就需要编译为.css
的文件,一般是使用sass
命令来进行编译,在webpack
中使用loader
来编译该文件。
安装loader
npm install --save-dev node-sass sass-loader
在js中引入编写好的.scss
文件
import sass from './css/common.scss';
在module
中增加对scss
文件的规则
{ test: /\.scss$/, // use: ['style-loader', 'css-loader', 'sass-loader'] use: ExtractTextPlugin.extract({ fallback: "style-loader", use: ["css-loader", "sass-loader"] }) }
注意:CSS预处理不只有SASS,我这里只是以SASS为例来演示
webpack
对于css预处理的打包支持
第十一章 CSS3自动加前缀
我们经常会为css3的属性前缀而苦恼,-webkit-
,-moz-
,-ms-
,-o-
,一般都是通过http://www.caniuse.com来查询,现在有了webpack
自动加前缀的功能妈妈就再也不用担心我的学习啦~~
npm install postcss-loader autoprefixer --save-dev
在项目的根目录下创建文件postcss.config.js
module.exports = { plugins: [ require('autoprefixer') ] }
在module
中修改对于css文件的规则
{ test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: "style-loader", use: [{ loader: "css-loader", options: { importLoader: 1 } }, "postcss-loader"] }) }
打包以后发现css3
属性的前缀就可以自动加上啦啦啦~~
第十二章 babel
现在越来越多的项目已经采用ES6
甚至ES7
ES8
的新特性来编写代码了,但有些语法并不能直接被浏览器识别,这就需要转化成浏览器可以直接识别的代码,就需要用到babel
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react
在module
中修改对于js
jsx
文件的规则
{ test: /\.(js|jsx)$/, use: { loader: 'babel-loader', options: { presets: ['env', 'react'] } } }
打包成功会发现新语法已经转化为ES5
的语法了
第十三章 打包注释
有的时候我们需要在文件中直接打包进去一些注释信息,webpack
自带的BannerPlugin
插件就可以帮我们实现这个功能。在plugins
中增加
new webpack.BannerPlugin('成哥所有,翻版必究!'),
第十四章 打包第三方类库
项目中我们经常需要用到第三方类库,比如jquery
vuejs
等,这就需要我们进行相应的配置。
安装第三方类库,这里以jquery
vuejs
为例
npm install jquery vue --save
在plugins
中增加
new webpack.optimize.CommonsChunkPlugin({ name: ['jquery', 'vue'], filename: 'assets/js/[name].js', minChunks: 2 })
总结
webpack
的入门指南算是总结完了,其实webpack
的强大之处还远不止于此,我只是在自己实践中总结下来一些常用的功能,希望可以对入门webpack
的小伙伴有所帮助。