本节咱们将要说到的实战场景目录:javascript
- 入门配置
- 建立单页面应用
- 接入babel
- 接入scss
- 接入vue
- 分离javascript与css
- 压缩javascript
- 压缩css
- 提取javascript公共代码
- 加入代码规范检测
- 搭建本地服务
- 建立多页面应用
目录结构以下: css
webpack.config.js配置以下:html
const path = require('path');
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist') //必须是绝对路径
}
};
复制代码
以上是一个最基础的配置,咱们接下来一步一步的加入更多的功能.vue
首先,咱们经过第一节,能够知道了怎么将一个入口main.js打包成bundle.js了,那么入口文件确定是要引用在html中啊,那么,怎么建立html文件?怎么建立build之后的html文件,以及html文件如何引用入口js文件?答案就是 html-webpack-plugin。 点击查看官方文档java
该插件能够实现哪些功能呢?node
第一步:安装插件react
npm i html-webpack-plugin --save-dev
复制代码
第二步:配置插件jquery
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './index.html'
})
]
说明:
template:表示模版,即以哪一个html文件为模,在dist目录下生成新的html文件
filename: 即编译之后生成的html文件的名字
复制代码
注意:上面咱们说到不用咱们手动建立一个html文件,就能够在编译后自动生成一个index.html, 固然,咱们也能够建立一个html模版文件,而后经过template属性引入, 这样编译后生成的index.html内容就是咱们本身建立的模版html文件的内容)webpack
如下是咱们生成的index.html文件: es6
babel完成了两件事情:
- 它是一个javascript解释器,它能够将es6代码转换为es5代码,让咱们在使用语言新特性的时候,不用担忧兼容性问题。
- 它能够经过插件机制,根据需求灵活的拓展。
在 Babel 执行编译的过程当中,会从项目根目 录下 的 .babelre 文件中读取配置。 .babelrc 是一个 JSON 格式的文件,内容大体以下:
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
}
}],
"stage-2",
"react"
],
"plugins": ["transform-vue-jsx", "transform-runtime"]
}
复制代码
咱们来认识一下这两个属性:
第一步:在webpack中配置babel-loader。
module.exports = {
module: {
rules : [
{
test: /\.js$/ ,
use : ['babel-loader'],
}
//此处还能够在rules下配置其余loader
]
}
}
复制代码
第二步:在根目录下建立.babelrc文件,配置presets和plugins
{
"presets": [
"env"
],
"plugins": []
}
复制代码
注意:webpack4.x支持在package.json中直接配置babel属性,不用新建.babelrc便可
"babel": {
"presets": [
"env"
],
"plugins": []
}
复制代码
第三步:安装babel相关依赖
# Webpack 接入 Babel 必须依赖的模块
npm i -D babel-core babel-loader
#根据咱们的需求选择不一样的 Plugins 或 Presets
npm i -D babel-preset-env
复制代码
提示:以上实例代码主要用于说明整个接入webpack的过程,在不一样场景下,具体的配置和安装依赖状况也会有所不一样。
scss 即为了咱们书写css更方便且更有效率,出现了less,sass,scss等css的预处理器,那么,在最后部署上线的时候,依然要转成css,才能够在浏览器端运行。
第一步:安装依赖
#安装 Webpack Loader 依赖
npm i -D sass-loader css-loader style-loader
# sass-loader 依赖 node-sass
npm i 一D node-sass
复制代码
第二步:在module中配置
module:{
rules:[
{
test: /\.scss$/,
use: ["style-loader", "css-loader", "sass-loader"]
}
]
}
复制代码
说明:
以上是配置wepbakc接入scss的基本配置, 除此以外,咱们还能够加入优化配置:
你们可能都知道,vue,react等都是近些年来比较流行的mvvm框架,而咱们使用的过程当中,更可能是依赖vue-cli等自带的脚手架去生成项目模版,不须要咱们手动去配置,那么接下来,咱们就经过webpack去手动接入vue,这样有利于咱们更好的理解vue。
第一步:安装依赖
# Vue 框架运行须要的库
npm i -S vue
#构建所需的依赖
npm i -D vue-loader css-loader vue-template-compiler
复制代码
说明:
第二步:配置loader
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module:{
rules:[
{
test: /\.vue$/,
use: 'vue-loader'
}
]
},
plugins: [
new VueLoaderPlugin()
],
复制代码
注意:须要配置VueLoaderPlugin 插件,
第三步:引入vue文件
//此时就和vue-cli提供的模版main.js同样去引入vue和vue相关文件
import Vue from 'vue';
import App from './app.vue';
new Vue({
el: '#app',
render: h => h(App)
});
复制代码
默认状况下,咱们打包entry入口文件的时候,文件中所依赖的css等样式模块也会包含js中,那么,如何分离javascript和css,分别存放在不一样的文件中呢?
第一步:安装依赖
说明:Webpack 4.x已经再也不支持extract-text-webpack-plugin,推荐使用mini-css-webpack-plugin, 若是想继续使用该插件,请 参考该文档
此处,咱们依然用该插件来实现js与css的代码分离:
//安装插件
npm i extract-text-webpack-plugin@next --save-dev
注意: 后面的@next必须加上,webpack4.x只支持该版本
或者能够用一个新插件: mini-css-extract-plugin
复制代码
第二步:增长webpack配置
const ExtractTextPlugin = require ('extract-text-webpack-plugin');
module.exports = {
module:{
rules:[
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin({
filename: path.resolve(__dirname, '/style/bundle.css') //注意能够指定分离出来的css文件的指定目录
})
]
};
复制代码
例如:下面是一个文件目录结构:
咱们在main.js中引入了main.css这个样式文件,那么,经过咱们webpack打包,而且进行javascript与css分离,dist中就分别生成了独立的js文件和css文件。
经过上面的操做,咱们已经将javascript与css分离开来,打开css文件,咱们发现,此刻css文件是位被压缩的,
那接下来,咱们接入css压缩相关配置: 第一步:安装依赖
npm i optimize-css-assets-webpack-plugin --save-dev
复制代码
第二步:添加配置
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.export = {
plugins: [
//只要配置了该插件,便可对分离出来的css进行压缩
new OptimizeCssAssetsPlugin()
]
}
复制代码
最后,咱们再次build,发现dist中css已是被压缩的了。
首先说明一点,可能咱们会看到不少教程使用的是UglifyJsPlugin,不过是webpack4.x以前的版本可使用,webpack4.x已经不支持使用移除webpack.optimize.UglifyJsPlugin 压缩配置了, 推荐使用 optimization.minimize 属性替代。
代码以下:
module.exports = {
optimization: {
minimize: true //webpack内置属性,默认为true,
}
}
复制代码
注意:minimize属性默认为 true,即默认状况下build以后的js文件已是压缩的了,若是咱们不想压缩js,能够设置该属性为false,
咱们来看看实际压缩先后的区别:
一: 首先,咱们说明一下为何要提取公共代码?:
大型网站一般由多个页面组成, 每一个页面都是一个独立的单页应用。 但因为全部页面都 采用一样的技术枝及同 一套样式代码,就致使这些页面之间有很 多相同的代码。
若是每一个页面的代码都将这些公共的部分包含进去,则会形成如下问题 。
因此,在实际开发过程当中,咱们须要把公共的代码抽离成一个独立的文件,这样用户在首次访问网站是就加载了该独立公共文件,此时这些公共文件就被浏览器缓存起来了,切换到其余页面时,该公共文件就不用在从新请求,而是直接访问缓存接口。
二:实际开发中,都须要咱们提取哪些公共文件呢
一说到公共文件,咱们可能最早想到是一些公共的工具函数所在的common.js文件,这个公共文件中的工具函数会被多个页面同时使用,其实,还有一个base.js也就是最基础的文件,例如,咱们vue开发过程当中的vue.js,
因此,此处所说的公共文件包含如下两部分:
注意:此处咱们为何要把base.js也单独提取出来,而不是直接包含在common.js中呢? 答案:为了长期长期缓存base.js文件,
由于base.js中包含的都是一些基础库,并且是指定版本的,咱们平时开发过程当中,通常不会升级这些基础库的版本,全部只要基础库版本不升级,文件内容就不会变化,hash值也不会更新,那么以前在浏览器中留下的缓存也不会被更新,从而实现长期缓存。而common.js是依据咱们开发的内容来的,因此若是开发过程当中发生了变化,那么hash也变化,从新上线之后再次访问,原来的缓存的common.js就没法使用了,会使用新的common.js文件。
三: 最后,咱们来因此说一下,如何经过webpack提取公共代码?
首先说明如下:webpack4.x提取公共代码推荐使用:webpack内置的SplitChunksPlugin插件,4.x以前所使用的CommomsChunksPlugin已被淘汰
接下来,咱们来经过具体的例子试一下:
第一步:咱们建立了两个入口文件:main.js 和 index.js, 还有一个公共的common.js文件,同时再安装一个lodash第三方库,而后两个入口文件中,分别引入common.js和lodash;
// mian.js和index.js
import './assets/js/common';
import 'lodash';
复制代码
第二步:配置多入口文件:
module.export = {
entry: {
main: './src/main.js',
index: './src/index.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
}
复制代码
第三步:此时,咱们执行npm run build命令,生成的dist文件夹以下:
此时,咱们引入的lodash和common.js其实分别在main.bundle.js和index.bundle.js各打包了一份,很显然,这样是不对的,那么如何把common.js和lodash分离打包成独立的文件呢? 答案就是splitChunks属性
第四步:配置splitChunks属性
module.exports = {
optimization: {
splitChunks: {
chunks: "async",
}
}
}
复制代码
此时,咱们执行npm run build发现 dist中的文件没有任何变化,并无将 公共模块分离出来,缘由是为何呢?
webpack4.x其实默认会将公共文件抽取出来的,只不过chunks属性默认是async, 顾名思义该词是异步的意思,也就是说默认状况下,webpack4.x只会将异步的公共模块分离成独立的文件, 而咱们手动引入的common.js和lodash是同步引入的,因此没有分离出来,因此咱们须要把chunks属性改成‘initial’ 或者‘all’
module.exports = {
optimization: {
splitChunks: {
chunks: "initial",
}
}
}
复制代码
咱们再来看一下dist目录:
可是还差一步:如何让common.js和lodash分别分离成独立的文件呢?
首先,咱们分析如下缘由,实际上是minSize属性致使的,它默认值为30000,也就是说webpack4.x只会将文件大小大于3k的公共文件分离出来,而咱们目前的common.js大小还不够,因此没有单独分离成一个文件,很显然,此时只须要修改minSize的值便可。
module.exports = {
optimization: {
splitChunks: {
chunks: "initial",
minSize: 0
}
}
}
复制代码
咱们再来看看dist目录:
啦啦啦,终于搞定了,lodash等属于nodemules中的公共依赖,都被分离到vendors~index~main.bundle.js中,而common.js被分离到main~index.bundle.js中,至此,如何提取公共js文件,大功告成!
Npm Script Chttps://docs.npm s.com/misc/scripts)是一个任务执行者。 Npm 是在安装 Node.js 时附带的包管理器, Npm Script 则是 Npm 内置的 一个功能,容许在 package.json 文件里 使用 scripts 宇段定义任务:
{
"scripts": {
'dev': 'node dev.js',
'build': 'node bulid.js'
}
}
复制代码
以上代码中的 scripts 字段是 一 个对象,每一个属性对应一段脚本,以上代码定义 了两 个任务 dev 和 build。 Npm Script 的底层实现原理是经过调用 Shell 去运行脚本命令, 例如执 行 npm run build 命令等同于执行 node build.j s 命令。
同时npm script能够执行node_modules内置的模块:
例如:
{
"scripts": {
"build": "webpack"
}
}
复制代码
检查代码时主要检查如下几项:
目前最经常使用的 JavaScript 检查工具是 ESlint (eslint.org),它不只内 置了大量的经常使用检查 规则,还能够经过插件机制作到灵活扩展。
npm i eslint --save-dev //局部安装
或者
npm i eslint -g //全局安装
复制代码
第二步:建立.eslintrc
{
//从 eslint :recommended 中继承全部检查规则
"extends" : "eslint:recommended",
// 再自定义一些规则
”rules”:{
//须要在每行结尾加 ;
"semi":["error","always"] , //须要使用""包裹字符串
"quotes" : [ "error", "double"]
}
}
复制代码
第三步:运行eslint命令
eslint yourfile . js
复制代码
该命令的做用就是检查yourfile.js文件的代码格式是否符合eslint的要求,若是有问题会报警提示:例如:
296:13 error Strings must use doublequote quotes
298 :7 error Missing semicolon sem工
复制代码
npm i eslint-loader -D
复制代码
第二步:添加loader
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter') // 默认的错误提示方式
}
},
enforce: 'pre', // 编译前检查
exclude: /node_modules/, // 不检测的文件
include: [__dirname + '/src'], // 要检查的目录
}
]
}
复制代码
第三步:新建.eslintrc.js
复制代码
stylelint (stylelint.io)是目前最成熟的 css 检查工具,在内置了大量检查规则的 同时,也提供了插件机制让用户自定义扩展 。 stylelint 基于 PostCSS,能检查任何 PostCSS 能解析的代码,例如 scss、 Less 等 。
npm i stylelint --save-dev
或者
ηpm i -g stylelint
复制代码
第二步:建立.stylelintrc文件
{
//继承 stylelint-config-standard 中全部的检查规则
"extends":"stylelint-config-standard",
// 再自定义检查规则
"rules": {
"at-rule-empty-line-before": null
}
}
复制代码
第三步:执行命令
stylelint ”yourfile.css”
复制代码
第一步. 搭建本地服务webpack-dev-server
npm install webpack-dev-server --save-dev
复制代码
第二步:在package.json配置npm script命令
scripts: {
"dev": 'webpack-dev-server --config webpack.dev.config.js'
}
复制代码
说明:此处咱们新建一个测试环境的webpack配置文件,用于区分正式环境和测试环境
第三步:配置devServer
module.exports = merge(baseWebpackConfig, {
mode: 'development',
devServer: {
port: 9999,
contentBase: './dist',
},
plugins: [
]
});
复制代码
此时,咱们在浏览器中输入:localhost:9999 就能够访问到咱们的页面了。
第四步:实现实时刷新 即,只要代码改动,保存之后,浏览器自动刷新
module.exports = merge(baseWebpackConfig, {
mode: 'development',
devServer: {
inline: true, //实时刷新
},
plugins: [
]
});
复制代码
第五步:实现热更新
module.exports = merge(baseWebpackConfig, {
mode: 'development',
devServer: {
hot: true, //热替换
},
plugins: [
// 热更新插件
new webpack.HotModuleReplacementPlugin()
]
});
复制代码
注意一下三者的区别:
首先说明一下单页面和多页面的区别:
方式1:建立多个入口文件,同时结合 html-webpack-plugin 建立多个html文件,实现多页面应用
方式2: 使用web-webpack-plugin 插件
说明:此处暂不说明具体配置,你们只需清除单页面和多页面的区别,同时,能够采用一下两种方式去实现多页面应用。
经过本节的十几个实战场景,相信你们已经基本了解了webpack整个配置的机制,什么场景下采用什么样的配置,固然,你们没必要彻底记住具体的配置,但要知道什么场景下,用什么样的loader或者plugin等, 同时,我的以为最重要的是 理解这些场景下所蕴含的思想,例如为何要区分出现单页面?为何要分离javascript与css?为何压缩文件等等,这些才是最关键的,以后,咱们专门用一节去讲述webpack背后所包含的这些思想,你们敬请期待吧!