likes
comments
collection
share

webpack的概念和基础使用

作者站长头像
站长
· 阅读数 14

1.webpack的概念及主要功能

概念: WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

功能

  1. 编译,包括JavaScript的编译,Css的编译;
  2. 文件的压缩,打包,合并,公共模块图区等;
  3. 图片资源的处理,如压缩;
  4. Tree-shaking等优化Javascript工具;
  5. Webpack-dev-sever、Eslint、热更新等帮助开发的工具

2.webpack的安装

在安装webpack之前首先要安装node

本文中所使用的webpack版本为4.35.2,webpack-cli为3.2.3

2.1 全局安装

安装命令 npm install webpack@4.35.2 -g

版本4之后还需要搭配一个cli

npm install webpack@4.35.2 webpack-cli@3.2.3 -g

2.2 局部安装

安装命令 npm install webpack@4.35.2 --save-dev

版本4+ npm install webpack@4.35.2 webpack-cli@3.2.3 --save-dev

建议在使用的时候建议大家进行局部安装,因为我们做项目时可能有多个,每一个webpack的版本各不相同,有些可能是很久以前的版本,如果全局安装的话,会造成打包编译出现问题。

2.3 初始化

我们创建一个test文件夹,并进入其中,使用命令npm init -y进行package.json文件初始化,这个时候我们会发现test文件夹中多了package.json文件

webpack的概念和基础使用

webpack的概念和基础使用 其中main属性为编译的入口文件,然后我们在test根目录下进行webpack局部安装

npm install webpack@4.35.2 webpack-cli@3.2.3 --save-dev

安装成功之后我们会发现package.json中多了webpack和webpack-cli对应的版本号,并且test目录下多了package-lock.json和node_modules依赖

webpack的概念和基础使用

2.3 webpack的核心概念

  1. entry
  2. output
  3. loader
  4. plugin

在下文有详细介绍

3.用webpack打包一次

3.1 创建入口文件

package.json文件中的main属性,为打包文件的入口,那我们在test文件夹下创建index.js文件,并写入一段代码

webpack的概念和基础使用

3.2创建配置打包文件

在test文件夹下创建webpack.config.js文件,并写入对应代码

module.exports={
}

注意 当我们没有指定打包配置文件时,webpack.config.js文件即为默认配置文件,webpack会默认在根目录下寻找webpack.config.js文件作为配置文件

3.2.1 entry

entry为文件入口,代码从这里进行编译,程序开始的起点,其写法有几种

module.exports={
  // entry:'./index.js', //以index.js为入口
  
  // entry:['./index.js','./index2.js'],//将两个入口文件打包成一个入口,如果要这么写需要在加上对应的入口文件
  
   //两个会打包成两个以app、app2为入口单应用页面程序
  //entry:{
  //  app: './index.js',
  //  app2:'./index2.js'  
  //},
  
  //常用
  entry:{
    app: './index.js'
  },
 } 

3.2.2 output

output为文件的出口,最终的打包结果会根据output的定义输出,会影响到资源的路径 其中output中的filename是出口的文件名

webpack的概念和基础使用

3.3如何使用局部webpack进行打包

我们使用的是局部webpack,这个时候直接使用webpack命令进行打包会优先使用全局的webpack进行编译,这个时候需要我们在package.json的scripts中添加一行命令

webpack的概念和基础使用 build可以改成任意的名字,

3.4webpack的第一次打包

然后我们在控制台输入npm run build,如果输入别名了就是npm run <别名> ,这样就会执行webpack命令,但是和在终端中直接输入webpack是有区别的,scripts中的webpack默认会先使用局部的webpack,再去找全局的webpack,然后会看到控制台如下图输出,并且我们test文件夹下会多出dist文件夹里边有一个app.js文件,这个时候我们的第一次打包代表成功了 webpack的概念和基础使用

3.3output中的filename

注意 除了在3.2.2中output中的filename那种固定的写法外,我们还有不固定的写法,如下

module.exports={
  entry:'./index.js', //入口文件

  output:{//出口
    filename:'./js/[name].[hash].js' //即可打包如main.jasidjasidji.js,该文件会在dist/js下
  }
}

name为文件名,指entry中的key值,默认为main;hash为一串字符串 hash也可以进行截取,如

module.exports={
  entry:'./index.js', //入口文件

  output:{//出口
    filename:'./js/[name].[hash:4].js' //即可打包如main.jasi.js,改hash只有4位
  }
}

也可以写成下例:path为打包的地址, __dirname代表项目绝对路径

module.exports={
  entry:{
    app:'./index.js' //入口文件
  },

  output:{//出口
    // name为entry中的key,也就是现在的app
     // __dirname代表项目绝对路径
    path:__dirname + '/src/mybundle',//打包到指定路径中,若不填写则默认到dist文件夹下
    filename:'./js/[name].[hash:4].js' 
  }
}

重新打包后会生成src/mybundle/app.7aa1.js,name变成了app,hash只有4为,文件存放地址在test目录下的src/mybundle

webpack的概念和基础使用

4.webpack中js编译

4.1编译es6

4.1.1 Babel-loader

编译需要安装的loader:babel-loader,babel/core

babel-loader为编译es6要用到的loader,babel/core 为babel-loader的编译核心,babel-loader是利用babel/core来进行编译的

//安装命令 局部安装babel-loader
npm install babel-loader @babel/core --save-dev 

安装好之后会在package.json中写入

webpack的概念和基础使用 然后在index.js文件写入es6的语法

//index.js文件
setTimeout(()=>{
  console.log(1)
},1000)

在webpack.config.js中编写配置

loader是写在module中rules数组下,每个itme为一条loader,test为匹配规则(现在写的是以.js结尾的文件),use中写需要使用的loader

module.exports={
  entry:{
    app:'./index.js' //入口文件
  },

  output:{//出口
    // name为entry中的key,也就是现在的app
     // __dirname代表项目绝对路径
    //path:__dirname + '/src/mybundle',//打包到指定路径中,若不填写则默认到dist文件夹下
    filename:'./js/[name].[hash:4].js' 
  },
  module:{
    rules:[{
      test: /\.js$/, //匹配规则,以.js结尾的文件
      use: 'babel-loader'
    }]
  },
}

再去打包后,发现我们的代码并没有转成es5,是我们的babel-loader没有生效吗?并不是的,只是我们缺少一些配置,babel默认只转换新的 JavaScript 语法,比如箭头函数、扩展运算(spread)。不转换新的 API,例如IteratorGeneratorSetMapsProxyReflectSymbolPromise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转译。如果想使用这些新的对象和方法,则需要为当前环境提供一个垫片(polyfill)

webpack的概念和基础使用

4.1.2 Babel-preset

配置中缺少Babel-preset,babel-preset是储存javascript不同标准的插件,通过使用正确的presets,告诉babel按照哪个规范编译

//安装命令
npm install @babel/preset-env --save-dev

Babel-prese中的targets配置

targets是preset的核心配置,告诉preset编译的具体目标

  1. targets可以:以browsers(浏览器)为目标(通常情况)
  2. 以node的版本为目标
  3. 以特定的浏览器为目标
//webpack.config.js文件
module.exports={
  entry:{
    app:'./index.js' //入口文件
  },

  output:{//出口
    // name为entry中的key,也就是现在的app
     // __dirname代表项目绝对路径
    // path:__dirname + '/src/mybundle',//打包到指定路径中,若不填写则默认到dist文件夹下
    filename:'./js/[name].[hash:4].js' 
  },
  module:{
    rules:[{
      test:/\.js$/, //匹配规则,以.js结尾的文件
      use:{
        loader:'babel-loader',
        options:{
          presets:[
            //编译es6的语法,对es6的方法是无能为力的
            ["@babel/preset-env",{
              "targets":{
                "browsers":["> 0%"] //写1%>无法正常进行转换,以大于市场份额0%的浏览器作为编译目标
              }
            }]
          ] 
        },
         
      }
    }]
  },
}

打包好了之后进入打包文件,会发现已经对es6语法进行了编译

webpack的概念和基础使用

4.1.3 Babel-polyfill & Babel-transform-runtime

注意Babel-preset只能对es6的语法进行处理,对es6的方法就无能为力了,这个时候我们可以使用babel-polyfill或者babel-transform-runtime这两种方式来解决。

两者的区别

babel-polyfillbabel-transform-runtime
生成一个全局对象生成一个局部对象
一般用于项目的开发一般用于框架开发

4.1.3.1 Babel-polyfill的安装及使用

//安装命令
npm install babel-polyfill --save-dev

在index.js文件中引入使用,并且使用es6的方法,如果不引用会发现该方法无法被解析

webpack的概念和基础使用 打包后会发现该文件体积明显增大,在打包的代码里生成一个全局对象,这个对象里定义了我们一些es6api的实现,也就是说把我们需要用到的需要编译的es6方法全部用我们的es5来实现一遍,放到这个全局对象里,这样我们在代码里写的es6方法实际上是使用的babel-polyfill里写的方法 webpack的概念和基础使用

webpack的概念和基础使用 不在index.js中引用,也可以写到我们的webpack.config.js文件的entry上,效果是一样的。 webpack的概念和基础使用

4.1.3.2 Babel-transform-runtime的安装及使用

Babel为了解决Babel-polyfill的问题,提供了单独的包babel-runtime用以提供编译模块的工具函数,启用插件babel-plugin-transform-runtime后,Babel就会使用babel-runtime下的工具函数。

babel-runtime插件能够将这些工具函数的代码转换成require语句,指向为对babel-runtime的引用。每当要转译一个api时都要手动加上require('babel-runtime')。简单说 babel-runtime 更像是一种按需加载的实现,比如你哪里需要使用 Promise,只要在这个文件头部 require Promise from 'babel-runtime/core-js/promise'就行了。

为了方便使用 babel-runtime,解决手动 require 的苦恼。babel-plugin-transform-runtime会分析我们的 javascript 中,是否有引用 babel-rumtime 中的垫片(通过映射关系),如果有,就会在当前模块顶部插入我们需要的垫片。

transform-runtime 是利用 plugin 自动识别并替换代码中的新特性,你不需要再引入,只需要装好 babel-runtime 和 配好 plugin 就可以了。

好处是按需替换,检测到你需要哪个,就引入哪个 polyfill,如果只用了一部分,打包完的文件体积对比 babel-polyfill 会小很多。而且 transform-runtime 不会污染原生的对象,方法,也不会对其他 polyfill 产生影响。

所以 transform-runtime 的方式更适合开发工具包,库,一方面是体积够小,另一方面是用户(开发者)不会因为引用了我们的工具,包而污染了全局的原生方法,产生副作用。

//安装命令
npm install @babel/plugin-transform-runtime @babel/runtime --save-dev
//配置
"plugins:[
      ["@babel/transform-runtime"]
    ]

在写法上与Babel-polyfill有所不同,它作为Babel的插件是写在plugins里。需要注意的是,使用@babel/plugin-transform-runtime,不会对实例方法比如"foobar".includes("foo")进行转换,因为这将需要对已存在的内置对象进行修。

我们先修改一下index.js文件,添加一个async函数

webpack的概念和基础使用

安装好后,我们先禁用掉Babel-polyfill,配置plugin-transform-runtime,进行打包。

webpack的概念和基础使用 打包后我们会发现文件体积相比之前使用Babel-polyfill(90多kb)小了很多,并且成功加入了相关的垫片。

小结

babel-loader,babel-core,babel-preset的关系

编译ES6需要的 babel-loader 与 @babel/core ,@babel/core 是 babel-loader 的核心。babel-preset 是储存 javascript 不同标准的插件,通过使用正确的 babel-presets ,告诉 babel 按照哪个规范编译。否则 babel-loader 不会进行ES6的编译。

.babelrc

如果我们的webpack.config.js中的options越写越多,就会看起来不美观,也不方便维护,这时我们可以写成一个单独的文件,在test文件夹下新建一个.babelrc的文件,必须是这个名字,我们的babel会自动读取这个文件下的内容。

webpack的概念和基础使用

webpack的概念和基础使用

4.2 编译ts

webpack的概念和基础使用

//安装命令
npm install typescript@2.9.2 ts-loader@4.5.0 --save-dev

注意 此处安装typescript和ts-loader要注意版本,如果版本和当前webpack不太适配的话,打包会报错,同学们可以安装一下其它版本试试。 安装成功后package.json会写入。 webpack的概念和基础使用 新增一个test.ts文件,并书写一段ts代码,然后再index.js引用

webpack的概念和基础使用

webpack的概念和基础使用 webpack.config.js中写入ts-loader

{
      test:/\.tsx?$/, // /\.tsx?$/ ts文件有以ts后缀或者tsx后缀 所以此处写tsx?
      use:'ts-loader'
    }

webpack的概念和基础使用 新增tsconfig.json文件,并写入配置

//tsconfig.json文件
{
  //编译配置
  "compilerOptions": {
    "module": "commonjs",//使用什么样的模块化规范
    "target": "es5" //编译成什么语法
  },
  "exclude": ["./node_modules"] //不处理什么文件
}

webpack的概念和基础使用 进行打包后就可以看到我们所写的ts语法已经被处理

5.css的编译和处理

5.1 css的第一次打包

webpack是以js文件为入口进行打包的,那么项目的css怎么办?如何引入css?

css可以通过js文件引入,但必须使用相应的loader

  1. css-loader,让css可以被js正确的引入;
  2. style-loader,让css被引入后可以被正确的以一个style标签插入到页面;
  3. 两者的顺序很重要,要先经过css-loader的处理,再由style-loader处理。
//安装命令,需要安装适合webpack版本的
npm install style-loader@0.23.1 css-loader@3.0.0 --save-dev

新增test.css和test2.css,并写入简单的样式

/* test.css文件 */
*{
  background-color: red;
}
/* test2.css文件 */
body{
  font-size: 20px;
}
.fzcolor{
  color: blue;
}

index.js入口文件引入test.css和test2.css

import "./test.css"
import "./test2.css"
console.log(123)

webpack的概念和基础使用 新增index.html文件,其中script标签的src地址是我们webpack.config.js文件中output打包固定的地址名称

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <div id="mydiv">
    <!-- 此处src引用的是打包好的js文件,app.bundle.js
    是在webpack.config.js中output固定的filename -->
    <script text="text/javascript" src="./dist/js/app.bundle.js"></script>
  </div>
</body>
</html>

webpack的概念和基础使用 书写webpack.config.js中的loader配置

module.exports={
  entry:{
    // app:['babel-polyfill','./index.js'] //入口文件
    app:['./index.js'] //入口文件

  },

  output:{//出口
    // name为entry中的key,也就是现在的app
     // __dirname代表项目绝对路径
    // path:__dirname + '/src/mybundle',//打包到指定路径中,若不填写则默认到dist文件夹下
    filename:'./js/[name].bundle.js' 
  },
  module:{
    rules:[{
      test:/\.js$/, //匹配规则,以.js结尾的文件
      use:{
        loader:'babel-loader',
      }
    },{
      test:/\.tsx?$/, // /\.tsx?$/ ts文件有以ts后缀或者tsx后缀 所以此处写tsx?
      use:'ts-loader'
    },{
      test:/\.css$/,
      
      use:[{
        loader:'style-loader',
      },{
        loader:'css-loader',
      }]
    }]
  },
}

注意use是多个的话可以写成数组形式;上文讲到要先经过css-loader的处理,再由style-loader处理,但是在use里是从下往上加载,所以要先写style-loader。

打包之后,直接在浏览器打开我们的index.html,会发现我们的样式已经生效。

5.2 核心配置

style-loader的核心配置

  1. instertAt :style标签插入再header哪一块区域或某个div;
  2. insertInto:插入指定的dom
  3. singleton:是否合并为一个style标签
  4. transform:在浏览器环境下,插入style到页面前,用js对css进行操作
module.exports={
  entry:{
    app:['./index.js']
  },
  output:{
    filename:'./js/[name].bundle.js' 
  },
  module:{
    rules:[{
      test:/\.css$/,
      use:[{
        loader:'style-loader',
        options:{
          // instertAt:'top',//'bottom'style标签插入再header那一块区域
          // instertAt:{
          //   before:'#mydiv'
          // }
          insertInto:'#mydiv', //插入指定的dom
          singleton:true ,//是否合并为一个style标签
          transform:'./transform.js'//在浏览器环境下,插入style到页面前,用js对css进行操作
        }
      },{
        loader:'css-loader',
      }]
    }]
  },
}

在transform配置上写的是一个文件地址,那我们在text目录下新增transform.js文件

//transform.js
module.exports = function(css){
  if(window.screen.width<500){
  //宽度小于500时将红色替换为黄色
    css = css.replace('red','yellow')
  }
  return css //必须要将处理过后的css return出去
}
//style标签在插入浏览器生效之前最后一次对css进行修改

重新打包后,浏览器初始背景为红色,切换到手机模式,小屏500内后重新刷新,会发现背景变为黄色。

css-loader的核心配置

  1. minimize:是否压缩css,webpack4中已移除
  2. module:是否使用css模块化,类似与less可以使用变量
  3. alias:css中的全局别名,webpack4中已移除

开始配置css-loader

{
  loader:'css-loader',
  options:{
    modules:true,
  }
}

webpack的概念和基础使用

在test.css和test2.css文件中新增一些样式,global定义全局样式,local定义局部样式,composes继承

/* test.css */
*{
  background-color: red;
}
.border-yellow{
  border: 4px solid yellow;
}
:global .box{
  border: 4px solid green;
}
/* test2.css */
body{
  font-size: 20px;
}
.fzcolor{
  color: blue;
}
 :global .borders{
    border: 4px solid white;
  }
 
 :local .div1{
  width: 50px;
  height: 50px;
  background-color: pink;
  composes: fzcolor; /* 这种无法使用global定义的,并且只能是当前文件的样式 */
  composes: box from global;/*可以使用global,包括其他文件*/
  composes: border-yellow from './test.css';/*使用其他文件的普通样式*/
}

然后我们重新进行打包,会发现所写的样式名称已经变成了一串编码,但是并没有引入到mydiv中,所以没有生效。并且可以发现这里只有对设置为local或者没有任何设置的类型进行了编码,对global或者是标签之类的没有进行编码。

webpack的概念和基础使用 所以我们需要通过js来控制我们的类名,接下来在index.js中进行一下修改

// 之前的引用方式
// import "./test.css"
// import "./test2.css"

//modules后的书写方式
import test from  './test.css'
import test2 from  './test2.css'
document.getElementById('mydiv').setAttribute('class',test2.div1)

webpack的概念和基础使用 然后我们重新进行打包,会发现样式已经成功生效。

webpack的概念和基础使用 但是这个类名难以阅读理解,我们可以在webpack.config.js文件中对css-loader进行一下处理,然后重新进行打包

{
        loader:'css-loader',
        options:{
          modules:{
             //path name 文件名,local 初始类名, hash 哈希值
            localIdentName:'[path][name]_[local]_[hash:4]'
          }
        }
      }

webpack的概念和基础使用

less、sass等预处理语言的编译

less、sass编译所需loader

  1. less: less、less-loader
  2. sass: sass-loader、node-sass

less

//安装命令,因为使用的webpack是版本4,所以此处对less和less-loader的版本有所要求
npm install less@3.9.0 less-loader@5.0.0 --save-dev

然后更改test.css和test2.css为test.less和test2.less文件,并更改index.js文件中的引用,test.less文件中增加一个less写法的变量并使用,test2.less文件并引用对应的样式

webpack的概念和基础使用 webpack的概念和基础使用
/* test.css */
@base: green;
* {
  background-color: red;
}
.border-yellow {
  border: 4px solid @base;
}
:global .box {
  border: 4px solid green;
}
/* test2.css */
body {
  font-size: 20px;
}
.fzcolor {
  color: blue;
}
:global .borders {
  border: 4px solid white;
}
:local .div1 {
  width: 50px;
  height: 50px;
  background-color: pink;
  composes: border-yellow from "./test.less";
}

更改webpack.config.js中相关配置,将test:/\.css$/ 改为test:/\.less$/并加入配置{loader:'less-loader'}这里依旧要注意顺序,我们less-loader将less文件处理成css文件将会交给css-loader进行处理、然后在由style-loader处理

{
      test:/\.less$/,
      // npm install style-loader@0.23.1 css-loader@3.0.0 --save-dev
      use:[{
        loader:'style-loader',
        options:{
          insertInto:'#mydiv', //插入指定的dom
          singleton:true ,//是否合并为一个style标签
          transform:'./transform.js'//在浏览器环境下,插入style到页面前,用js对css进行操作
        }
      },{
        loader:'css-loader',
        options:{
          modules:{
            localIdentName:'[path][name]_[local]_[hash:4]'
          }
        }
      },{
        loader:'less-loader',
      }]

重新打包后会发现div有了绿色边框已经生效。

提取css代码为单独文件

  1. 安装对应的插件(extract-text-webpack-plugin)
  2. 改造loader处的写法,把use改为使用extract-text-webpack-plugin
  3. 在plugin处添加(把extract-text-webpack-plugin加入到plugin里)
//安装命令,注意安装适配当前webpack的版本
npm install extract-text-webpack-plugin@4.0.0-beta.0 --save

在webpack.config.js中引入extract-text-webpack-plugin插件,改写use,并加入plugin

var extractTextCss = require('extract-text-webpack-plugin')
module.exports = {
  entry: {
    // app:['babel-polyfill','./index.js'] //入口文件
    app: ['./index.js'] //入口文件

  },

  output: {//出口
    // name为entry中的key,也就是现在的app
    // __dirname代表项目绝对路径
    // path:__dirname + '/src/mybundle',//打包到指定路径中,若不填写则默认到dist文件夹下
    filename: './js/[name].bundle.js'
  },
  module: {
    rules: [{
      test: /\.js$/, //匹配规则,以.js结尾的文件
      use: {
        loader: 'babel-loader',
      }
    }, {
      test: /\.tsx?$/, // /\.tsx?$/ ts文件有以ts后缀或者tsx后缀 所以此处写tsx?
      use: 'ts-loader'
    }, {
      test: /\.less$/,
      // npm install style-loader@0.23.1 css-loader@3.0.0 --save-dev
      use: extractTextCss.extract({
        fallback: {
          loader: 'style-loader',
          options: {
            insertInto: '#mydiv', //插入指定的dom
            singleton: true,//是否合并为一个style标签
            transform: './transform.js'//在浏览器环境下,插入style到页面前,用js对css进行操作
          }
        },
        use: [{
          loader: 'css-loader',
          options: {
            modules: {
              localIdentName: '[path][name]_[local]_[hash:4]'
            }
          }
        }, {
          loader: 'less-loader',
        }]
      })
    }]
  },
  plugins:[
    new extractTextCss({
      filename:'[name].min.css'
    })
  ]
}

然后重新打包,会发现额外的增加了app.min.css文件,然后我们需要在index.html中手动通过link标签引入app.min.css文件

webpack的概念和基础使用 webpack的概念和基础使用

webpack的概念和基础使用

postcss和postcss-loader

//安装命令autoprefixer 属于postcss第三方插件需要单独安装
npm install postcss@7.0.17 postcss-loader@3.0.0 autoprefixer@9.6.1  --save

更改webpack.config.js配置增加postcss-loader,注意顺序,并在test.less文件中增加display:flex样式

use: extractTextCss.extract({
        fallback: {
          loader: 'style-loader',
          options: {
            insertInto: '#mydiv', //插入指定的dom
            singleton: true,//是否合并为一个style标签
            transform: './transform.js'//在浏览器环境下,插入style到页面前,用js对css进行操作
          }
        },
        use: [{
          loader: 'css-loader',
          options: {
            modules: {
              localIdentName: '[path][name]_[local]_[hash:4]'
            }
          }
        },{
          loader: 'postcss-loader',
          options:{
            ident:'postcss',
            plugins:[
              require('autoprefixer')({
                "overrideBrowserslist":[ 
                  ">1%",'last 2 versions' //需要指定浏览器编译目标 类似于babel
                ]
              })
            ]
          }
        },{
          loader: 'less-loader',
        }]
      })
/* test.css */
@base: green;
* {
  background-color: red;
}
.border-yellow {
  border: 4px solid @base;
  display: flex;
}
:global .box {
  border: 4px solid green;
}

然后重新打包,打开app.min.css文件会发现给display:flex增加了对应前缀

webpack的概念和基础使用 总结

我们在大量使用loader时都需要配置Browserslist,这样会造成大量重复且容易不统一,那么有两种方式可以统一配置

  1. 在package.json配置中增加browserslist(推荐webpack的概念和基础使用
  2. 增加.browserslistrc文件,类似于.babelrc

6.html的编译和处理

在上文中都是手动引入js、css文件,其实在webpack中可以自动帮我们引入,需要用到html-webpack-plugin插件。

//安装命令
npm install html-webpack-plugin@3.2.0 --save-dev

相关配置

  1. filename: 打包生成后的html文件的名字(必填)
  2. tmplate: 指定一个html文件作为模板(必填)
  3. minify: 压缩html
  4. inject: 是否把js、css文件插入到html,插入到哪里
  5. chunks: 多入口时指定引入chunks 在webpack.config.js配置中引入该插件,然后添加到plugin中

6.1 filename、tmplate

var htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    entry:{ //*** },
    //***
    plugins:[
    
    //***
    
    new htmlWebpackPlugin({
      filename:'index.html',
      template:'./index.html'
    })
  ]
}

我们在index.html中删掉之前手动引入的js和css,然后进行打包,这个时候我们会发现dist中新增加了index.html文件,打开盖文件可看到里边已经自动引入可我们打包的js和css文件。

webpack的概念和基础使用 webpack的概念和基础使用

6.2 minify、inject

压缩时配置minify参数,接受的是一个对象,但是webpack也是使用的第三方,所以该对象是给第三方使用的

var htmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    entry:{ //*** },
    //***
    plugins:[
    
    //***
    
    new htmlWebpackPlugin({
      filename:'index.html',
      template:'./index.html',
      minify:{
        collapseWhitespace:true
      },
      inject: true, //默认为true,设置false时不引入js、css
    })
  ]
}

6.3 chunks

配置chunks,如果我们的entry是多入口时,这个时候不指定chunks那么就会将js都打包进去

module.exports={
  entry:{
    app: './index.js',
    app2:'./index2.js'  
  },
  
  //***
  
  plugins:[ 
  //*** 
    new htmlWebpackPlugin({
      filename:'index.html',
      template:'./index.html',
      minify:{
        collapseWhitespace:true
      }
      chunks:['index']
    })
   ]
 } 

通过该配置我们生成的打包结果只会将index.js打包到index.html中