这篇文章是我在学习过程当中对本身的一个记录和总结,也但愿能够帮助到和我当初一样对webpack有困惑的小伙伴javascript
我在自学webpack时也参考了不少大神的文章,参考的帖子太多就不一一谢过了,再次感谢各位大神的帮助css
文章中的每一个例子,我都是亲自测试过的,若是哪一个地方出现笔误等问题还请你们批评,我会及时改正html
本文使用的webpack版本是V3.8.1前端
现现在前端主流的三种框架VueJs、ReactJs、AngularJs都推荐与webpack共同使用,因此无论你是哪一种技术路线都不得不去学习了解webpack。那么webpack究竟是何方神圣?vue
官方说法是webpack是一个模块打包机,我我的理解是它能够把咱们在开发环境下的代码以及依赖文件等打包成在生产环境下能够直接使用的文件。也能够把一些浏览器不能直接运行的文件进行转化,好比是css、less、scss等。同时webpack也能够对代码进行优化,好比压缩、合并、文件缓存等等。在项目中咱们只须要把相应的配置文件配置好,那么接下来的工做就均可以交给webpack这个全能大神去完成了。java
英文: http://webpack.js.org/node
中文:https://doc.webpack-china.org/react
Github:https://github.com/webpack/we...jquery
npm install –g webpack
查看版本号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
呢?
这就须要搞清楚一个概念:开发模式
和 生产模式
。
项目在开发编码过程当中还未上线使用就属于开发模式,该模式下代码不须要压缩、合并等。好比编写可使用sass进行css预处理,使用ES6的语法来编写js代码。在开发模式下依赖的包安装的时候就须要使用--save-dev
,dev
表示开发的意思,使用--save-dev
安装的依赖包,会安装在package.json
的devDependencies
中,这些依赖包只在开发时候会使用到,在上线生成环境下就不须要了。
项目已经开发测试完成须要打包上线进行运营了,这时候就属于生产模式,改模式下的文件须要是最终浏览器能够直接解析的文件,不能再用如.scss
、.vue
、.jsx
等这样的文件了。在生产模式下依赖的包安装的时候就须要使用--save
,使用--save
安装的依赖包,会安装在package.json
的dependencies
中,这些依赖包是最终在上线时候使用到的,好比jquery.js
、vue.js
等。
你们在开发过程当中安装每一个依赖包的时候,都必定先考虑这个包是只有开发模式下能用到,仍是在生产模式下也须要用到,其实你们按照这个思路把下面的文章都看完,应该就能够对
--save-dev
和--save
有一个本身的理解了
无论学习什么语言或工具,Hello World都是必不可少的。
src:存放开发环境下的文件,也就是咱们平时写的代码都在这里面
dist:存放生产环境下的文件,也就是打包后的文件,项目上线时把
dist
文件夹中的内容拷贝到服务器上就可使用了node_modules:是自动生成的存放依赖包的文件夹,使用
npm install
命令安装依赖包
在src目录下,新建文件helloworld.js
alert('Hello World!');
在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里能够配置服务,这样的好处是页面再也不使用本地协议打开,而是经过服务打开,这样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
来访问个人网站。
在项目中,咱们须要把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文件须要进行打包,在入口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文件单独分离出来,而不是打包到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文件一般都是须要进行压缩的,这样能够减少文件体积加快加载速度,固然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"/>
须要依赖两个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-withimg-loader
npm install html-withimg-loader --save-dev
在module
中增长对html
文件的规则
{ test: /\.(html|htm)$/i, use: ['html-withimg-loader'] }
什么是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的属性前缀而苦恼,-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
属性的前缀就能够自动加上啦啦啦~~
如今愈来愈多的项目已经采用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
的小伙伴有所帮助。