ESModule&Webpack&npm_04


webpack基本使用详解

我们现在只学webpack的基本使用,在后续webpack高级中,coderwhy老师还会教手写loader这些,面向25k开发的。

webpack依赖图

1053

webpack打包的时候,会先找那个入口文件(默认index.js,找不到就报错,我们可以用命令或者在webpack.conig.js配置文件中指定入口文件),然后打包入口文件,发现入口文件又导入了其他模块,就又会打包其他模块,最终生成浏览器可以识别的静态代码。

tips:默认webpack只打包js的,那些css等文件需要使用对应的loader

比如vue框架,webpack本身是打包不了.vue文件的,但是现在大家都是用webpack打包,那么vue的开发者就需要写一个vue的loder出来供webpack使用识别.vue文件

css-loader的使用

1054

内联式和cli方式

1055

方式三常用

1056

我们要使用loder,就必须安装loader,命令npm install css-loader -D (因为是开发环境,所以-D)

然后我们在配置文件webpack.config.js文件中添加

module: {
  rules: [
    {
      // 告诉webpack匹配什么文件
      test: /\.css$/,
        //告诉用哪个loader解析
      use: [ 
              "css-loader",  
      ]
    }
  ]
}

但是我们发现,虽然能打包了,但是css不生效,因为css-loader只解析css,但是不会把css插入到html

我们还需要一个style-loader,照样是先安装后写入配置,主要use数组里面的loader是从下面往上面执行(如果是缩写,就从右向左),所以得先css-loader解析,后style-loader插入。

1057

我们loader有简写方法,但是不建议。

全称如use是一个数组,里面的没一个loader都是一个对象,但是如果我们不需要对这个loader配置,可以不写loader对象,直接写名称。不过当你要配置又要改回全称,还不如起初就全称。

1058

这些css和less如果直接引入对应的解析和插入loader确实可以生效,但是是通过内联式,也就是插入在index.html的style标签中生效的,如果需要单独生成一个css文件,需要做高级配置。

less文件的解析同理,安装一个less-loader即可。

const path = require("path")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./build")
  },
  module: {
    rules: [
      {
        // 告诉webpack匹配什么文件
        test: /\.css$/,
        // use: [ // use中多个loader的使用顺序是从后往前
        //   { loader: "style-loader" },
        //   { loader: "css-loader" }
        // ],
        // 简写一: 如果loader只有一个
        // loader: "css-loader"
        // 简写二: 多个loader不需要其他属性时, 可以直接写loader字符串形式
        use: [ 
          "style-loader",
          "css-loader", 
          "postcss-loader"
          // {
          //   loader: "postcss-loader",
          //   options: {
          //     postcssOptions: {
          //       plugins: [
          //         "autoprefixer"
          //       ]
          //     }
          //   }
          // }
        ]
      },
      {
        test: /\.less$/,
        use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
      }
    ]
  }
}

tips:css中有一个user-select:none属性,可以让用户无法选中内容

但是这个属性可能是不兼容一些浏览器的,所以得加前缀如-ms-user-select:none;-webkit-user-select

那我咋全知道哪些浏览器兼容哪些属性?一个个记吗?所以webpack中有一个postcss-loader可以自动判断,并帮我们添加前缀。

我们加了postcss-loader还是不行,因为它只是一个工具,你想使用它,还需要借助一个插件autoprefixer(也得npm install)。自动前缀的意思

我们需要把插件写进postcss-loader里面的option配置中,然后postcssOption插件plugin中

{
            loader: "postcss-loader",
            options: {
              postcssOptions: {
               plugins: [
                 "autoprefixer"
               ]
             }
            }

如果把这段代码写在webpack.confog.js中绝的各种配置太繁琐太难管理的话,可以单独抽取到一个postcss-config.js中(webpack的config中找不到,它会自动再寻找postcss-config.js)

好处:我们postcss不一定就css使用,less中也可能要使用,那么在less匹配的loader中也就要加配置代码,抽取到单独文件中,就避免了这一操作。

1059

单独配置文件的代码格式又和在webpack配置中写的格式不同,这都是loader的开发者自己定义的,我们记住就好了,其实也不需要记,因为我们现在是为了方便了解webpack的工作流程,所以学习这些东西,实际开发中这些配置脚手架都会帮我们配好。

问题:为什么建立了postcss.config.js,webpack中的loader就会来找这个文件读取配置,是如何绑定的?

它就是这样设置的,在这个loader被开发出来就写了这个逻辑,应该是通过名字绑定loader和配置文件js,如postcss-loader对应的就是postcss.config.js,通过前面那个单词来绑定。

然后通过commonjs模块化导出配置

postcss-preset-env预设

1060

它除了可以代替autoprefixer的加前缀功能,还能把浏览器不支持的,但是我们开发代码中有的新特性css写法,转换为浏览器支持的代码。

webpack打包图片

图片怎么导入到依赖图中,从而让webpack打包?

我们直接import xxx(随便起个名字) from “图片路径”即可,因为在webpack中任意文件其实都可以被看做一个模块。

// 引入图片模块
import zznhImage from "../img/zznh.png"
// 创建img元素
const imgEl = document.createElement("img")
imgEl.src = zznhImage
document.body.append(imgEl)

1061

比如打包图片等文件,其实webpack5已经给我们内置了与loader相似的功能,但是webpack默认是打包js,虽然它有打包图片的功能,我们需要在webpack.config.js中配置如下

1062

我们先匹配结尾为这些名称的文件,然后type:“asset”

tips:webpack.config.js是我们自己创造的文件,你随便写成什么名字开头都可以,比如demo.config.js

但是你在执行webpack命令的时候得带上,如npx webpack –config demo.config.js就是此次打包webpack运用那个js文件的配置。 为了方便我们通常在package.json中写一个script来包含这个命令

"scripts": {
  "build": "webpack --config demo.config.js"
},

那么我们只需要执行 npm run build即可,注意别写成npx了,这个执行script不需要去node_module找,你npx反而会出错找不到了。

1-其中asset/resource运行机制是把当前图片复制了一份到build文件夹中

2-asset/inline是把图片base64编码到了js文件中

3-resource方法会增加一次网络请求,inline方式会让js文件变的很大(会导致页面渲染慢),所以我们一般把大的图片用resource方法,小图片用inline方法

4-我们在type:“asset”,就写一个asset的话,配合paeser属性中的maxSize可以设置,自动判断大于多大的图片用resource,否则inline

tips:这些配置什么的单词很多,没必要记,知道有这个东西,会查阅文档就好了。

const path = require("path")
const { VueLoaderPlugin } = require("vue-loader/dist/index")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./build"),
    // assetModuleFilename: "abc.png"
  },
  resolve: {
    extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
    alias: {
      utils: path.resolve(__dirname, "./src/utils")
    }
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ "style-loader", "css-loader", "postcss-loader" ]
      },
      {
        test: /\.less$/,
        use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
      },
      {
        test: /\.(png|jpe?g|svg|gif)$/,
        // 1.打包两张图片, 并且这两张图片有自己的地址, 将地址设置到img/bgi中
        // 缺点: 多图片加载的两次网络请求
        // type: "asset/resource",

        // 2.将图片进行base64的编码, 并且直接编码后的源码放到打包的js文件中
        // 缺点: 造成js文件非常大, 下载js文件本身消耗时间非常长, 造成js代码的下载和解析/执行时间过长
        // type: "asset/inline"

        // 3.合理的规范:
        // 3.1.对于小一点的图片, 可以进行base64编码
        // 3.2.对于大一点的图片, 单独的图片打包, 形成url地址, 单独的请求这个url图片
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 60 * 1024
          }
        },
        generator: {
          // 占位符
          // name: 指向原来的图片名称
          // ext: 扩展名
          // hash: webpack生成的hash
          filename: "img/[name]_[hash:8][ext]"
        }
      },
      {
        test: /\.js$/,
        use: [
          { 
            loader: "babel-loader", 
            // options: {
            //   plugins: [
            //     "@babel/plugin-transform-arrow-functions",
            //     "@babel/plugin-transform-block-scoping"
            //   ]
            // } 
          }
        ]
      },
      {
        test: /\.vue$/,
        loader: "vue-loader"
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ]
}

如上的代码中的60*1024就是64kb的意思

1063

问题:当我们很多张图片被打包复制到了build文件中,但是build文件中的代码是hash过的名字,怎么办?

我们可以使用generator属性修改

generator: {
         // 占位符
         // name: 指向原来的图片名称
         // ext: 扩展名,如jpg,png
         // hash: webpack生成的hash,:8就是截取保留八位
         filename: "img/[name]_[hash:8][ext]"
       }

我们一般也是用占位符命名,不会写死,因为当有多张图片,不可能叫一样的名字,这样照样无法识别。

img/的作用是在bulid中生成一个img的文件夹来保存这些被打包的图片,否则bulid里面的东西太乱了

1064

webpack基本使用流程自我总结

1-首先npm init 生成一个package.json

2-安装webpack,npm install webpack webpack cli -D (-D是开发依赖局部安装的意思)

3-创造webpack.config.js文件。里面写webpack的配置,如使用哪些loder,打包输出的主js文件叫什么,webpack打包入口js是哪个等等各种配置。

4-从打包入口js处写入import引入代码,引入其他文件,形成依赖图,然后安装需要的各种需要的loder

5-在package.json设置一个script,让npx webpack –config webpack.config.js这行命令简化成一个script,当然你乐意敲可以不设置。(npx是因为模块的查找机制,当前路径是没有webpack的,因为是局部安装,环境变量中也没有webpack,所以npm会找不到,npx则会自动取node_module文件夹找)

6-运行webpack,得到build文件,里面就有打包好的原生js

webpack对js的打包babel作用

原先webpack一样能打包代码,但是如果我们写了es6的代码,打包后还是es6,就导致有的浏览器可能不兼容,那么如何把所有js代码转换为es5呢,就需要用到babel-loader

1065

babel命令行的使用

1066

1067

它本身是一个独立的工具,可以独立使用,也可以配合webpack,在webpack中写入配置使用。

注意这里不是一个babel-loader就把代码的箭头函数和const声明方式转换了,而是用了两个插件

{
   test: /\.js$/,
   use: [
     { 
       loader: "babel-loader", 
       // options: {
         //这里注释是因为我们使用了预设,这里的代码就不需要了
       //   plugins: [
       //     "@babel/plugin-transform-arrow-functions",
       //     "@babel/plugin-transform-block-scoping" 
       //   ]
       // } 
     }
   ]
 }

babel插件的单独配置文件

和postcss一样,babel也可以单独配置文件,防止webpack.config.js的代码太过冗杂

手动添加一个babel.config.js代码如下

module.exports = {
  // plugins: [
  //   "@babel/plugin-transform-arrow-functions",
  //   "@babel/plugin-transform-block-scoping"
  // ]
  presets: [
    "@babel/preset-env"
  ]
}

babel的预设

1068

有了这个预设,箭头函数和声明方式就不需要两个插件了,只需要一个预设

上面的命令是工具单独使用,我们一般不用的,我们都是在webpack中添加配置文件,配合babel使用,代码在上面写过了。

babel的常见预设有三个

1069

其中env就environment环境的意思。

babel的更加详细的使用和原理在工程化高级里面coderwhy老师会讲,这里我们知道有这个东西就好了。

对vue文件处理打包

我们开发vue,自然要npm install vue,注意这里不要加-D因为vue在生产和开发中都要用到,不像webpack只在我们开发的时候用到,但是这里也是局部安装,只存在于安装的这个文件内,全局安装是要-g的(vue也不会全局安装,因为不同项目用的版本不同)。

1070

vue比较特殊,安装了vue-loader,还必须安装一个插件

1071

resolve模块解析

它是帮助webpack从require和import中找到需要引入的模块

1072

const path = require("path")
const { VueLoaderPlugin } = require("vue-loader/dist/index")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./build"),
    // assetModuleFilename: "abc.png"
  },
  resolve: {
      //为import和require引入东西的时候,添加扩展名
    extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
      //alias设置别名
    alias: {
      utils: path.resolve(__dirname, "./src/utils")
    }
  },
 
}

当我们import或者require一个东西在页面上

如下

import { createApp } from 'vue'
import Hello from './vue_demo/Hello'
import { sum } from './utils/math'

1073

如果是一个文件,带了后缀名,就会直接打包

不带后缀名的话,就会webpack底层就会通过resolve.extensions自动为我们的文件添加后缀名。

怎么自动找到我的文件应该是什么后缀?不同的代码有不同的特点,webpack有自己的识别办法。

extensions是可以自己配置的

1074

我们可以自己配置,把需要自动加后缀名的后面加到resolve对象的extensions数组里面

所以如果我们不配置这个extensions那么直接import Vue文件的话,就会识别不到,然后报错无法找到import文件,所以必须自己写上.vue后缀,如hello.vue

如果是文件夹,如import utils from “./utils”那么就会默认变成import utils from “./utils/index”,这个index的后缀又会进行resolve.extensions匹配。

我认为根本没必要配,页面import或者require引入的时候,全部老老实实写个后缀还容易区分点

alias

1075

当我们的层级很深(项目中很容易遇到),那么引入写相对路径的话,就需要写好多个../非常不容易识别,所以我们经常在webpack.config.js内给它配置一个alias

//这里是webpack.config.js
resolve: {
      //为import和require引入东西的时候,添加扩展名
    extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
      //alias设置别名
    alias: {
      utils: path.resolve(__dirname, "./src/utils")
    }
  },

1076

webpack的常见插件和模式

1077

loader就是把各种各样后缀的代码,变成浏览器可以看得懂的三剑客代码

plugin可以做loader外的各种事情。优化打包,资源管理(管理文件等),环境变量注入等等各种拓展功能。

const path = require("path")
const { VueLoaderPlugin } = require("vue-loader/dist/index")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { DefinePlugin } = require("webpack")

module.exports = {
  mode: "production",
  entry: "./src/main.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "./build"),
    clean: true
    // assetModuleFilename: "abc.png"
  },
  resolve: {
    extensions: [".js", ".json", ".vue", ".jsx", ".ts", ".tsx"],
    alias: {
      utils: path.resolve(__dirname, "./src/utils")
    }
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [ "style-loader", "css-loader", "postcss-loader" ]
      },
      {
        test: /\.less$/,
        use: [ "style-loader", "css-loader", "less-loader", "postcss-loader" ]
      },
      {
        test: /\.(png|jpe?g|svg|gif)$/,
        // 1.打包两张图片, 并且这两张图片有自己的地址, 将地址设置到img/bgi中
        // 缺点: 多图片加载的两次网络请求
        // type: "asset/resource",

        // 2.将图片进行base64的编码, 并且直接编码后的源码放到打包的js文件中
        // 缺点: 造成js文件非常大, 下载js文件本身消耗时间非常长, 造成js代码的下载和解析/执行时间过长
        // type: "asset/inline"

        // 3.合理的规范:
        // 3.1.对于小一点的图片, 可以进行base64编码
        // 3.2.对于大一点的图片, 单独的图片打包, 形成url地址, 单独的请求这个url图片
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 60 * 1024
          }
        },
        generator: {
          // 占位符
          // name: 指向原来的图片名称
          // ext: 扩展名
          // hash: webpack生成的hash
          filename: "img/[name]_[hash:8][ext]"
        }
      },
      {
        test: /\.js$/,
        use: [
          { 
            loader: "babel-loader", 
            // options: {
            //   plugins: [
            //     "@babel/plugin-transform-arrow-functions",
            //     "@babel/plugin-transform-block-scoping"
            //   ]
            // } 
          }
        ]
      },
      {
        test: /\.vue$/,
        loader: "vue-loader"
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin(),
    // new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      title: "电商项目",
      template: "./index.html"
    }),
    new DefinePlugin({
      BASE_URL: "'./'",
      coderwhy: "'why'",
      counter: "123"
    })
  ]
}

有的插件不用引入,因为根本没用到里面的变量,如postcss的autoprefixer

有的插件比如下面的插件,你需要在plugin里面new 实例化东西,就必须引入了

引入的方式不同插件也不同,看插件作者怎么写的,如cleanwebpackplugin需要解构,但是htmlwebpackplugin又不需要解构

cleanWebpackPlugin

1078

dist文件夹就是打包后默认生成的文件夹,我们原先自己在webpack.config.js 的output中配置了文件夹名称为build,不配置默认是dist

tips:我们可以不用这个插件,在最新的webpack里面,配置中有一个output.clean可以和这个插件有相同的效果。

1083

文档https://webpack.docschina.org/concepts/

html-wepack-plugin

1079

1-意思就是说,webpack打包后,不会自动生成index.html在dist里面,这个插件可以自动生成一个html,这个html模板可以在node_modules里面的此插件的包的lib/default_index.js修改,或者在template指定模板。

2-默认生成title为WebpackAPP,我们可以在new的时候就修改

plugins: [
   // new CleanWebpackPlugin(),
   new HtmlWebpackPlugin({
     title: "电商项目",
     template: "./index.html"
   }),

3-其实我感觉这些都是鸡肋,我还不如自己建一个index.html,花里胡哨的全是配置恶心死了。

DefinePlugin

它是webpack内置的插件

1080

const { DefinePlugin } = require("webpack")

    new DefinePlugin({
      BASE_URL: "'./'",
      coderwhy: "'why'",
      counter: "123"
    })

1-它的作用就是注入一个变量,如上代码写在webpack.config.js中,就把当前项目注入了三个变量,比如在其他地方页面是可以直接使用coderwhy这个变量表示why字符串的

2-它默认注入了一个process.env.NODE_ENV,里面记录了当前的模式

Mode模式配置

1081

1082

1-通俗点就是写上production意思是生成的代码用于生产环境,不是在开发中,就又很多模块会去混淆压缩代码什么的,然后代码都在一行很难看懂

2-写development就是告诉webpack当前是在开发阶段,那么打包的代码,就能被开发者看懂。

webpack打包本地服务器

1084

打包需要开启本地服务器服务才能执行,以前我们是通过live server插件来打开的,有一个弊端

每次我们修改了代码,都需要重新打包。特别麻烦

webpack搭建的本地服务器去执行的话,就可以实时编译,我们写的代码一变,浏览器页面也可以更着变化。

开启本地服务器

1085

1-安装这个包

2-在webpack.config.js中的script中添加”serve”:“webpack serve –config wk.config.js”

3-npm run serve或者npx webpack serve –config wk.config.js

注意不能直接写npx webpcak -serve 因为如果你不指定配置,有的设置不存在,会报错的。

HMR热模块替换

1086

热模块更新,就是我们只改了一个东西,比如把console.log(‘1’)改成了console.log(‘2’)

我们不应该重新刷新整个页面,而是只改变这个console.log

在webpack-dev-server中其实内置了hmr热模块更新,也是默认打开的,所以下图中的hot:true可写可不写

1087

虽然直接支持也默认开启了,但是我们需要在打包入口文件.js中指定哪些模块发生更新时,进行HMR

问题:这玩意也太麻烦了,一个一个判断引入,我不如让它页面直接全部刷新呢,真是鸡肋!

1088

事实上这些是不需要我们自己配置的,在vue-loader中,这些东西都帮我们配置好了,我们这里学它只是了解有这个东西。

devServer配置

webpack-dev-server默认是在8080端口,我们也可以配置这些东西,比如指定端口。

devServer: {
   hot: true,
   // host: "0.0.0.0",
   // port: 8888,
       //自动打开浏览器
   // open: true
       //压缩文件
   // compress: true
 },

1089

host写成0.0.0.0的话,如我们本地ip地址为192.168.1.90,那么在学校机房,同一个局域网内,我的同学是192.168.1.91,同学也是可以在浏览器中通过192.168.1.90:8080访问到我们的页面 的

开发和生成环境

如何区分生产和开发环境

以前我们把所有的配置都写在webpack.config.js中,其实不同插件是运用于不同开发环境的,比如devServer插件是用于生产环境,而cleanWebpackPlungun是用于在开发环境帮我们删文件的。

如果它们都配置在webpack.config.js同一个地方,在运行的时候就会浪费一些性能,比如我们在开发的时候,就不需要devServer插件再去运行一下子了

1090

入口entry文件解析

1091

我们一般不修改content,就让它默认就好了

这里只需要知道,即使webpack.dev.config.js文件在config文件夹内,也就是多进去了一层,entry还是写./src/main.js的,而不是../src/main.js

webpack配置文件抽取公共部分

tips:为什么webpack里面的配置用的是commomjs?因为webpack是需要运行在node环境中的,node环境直接支持的就是commomjs模块化

上面说到要把webpack.config.js分为webpack.dev.config.js和webpack.product.config.js两个配置文件,在运行的时候可以节约性能,那么它们之间是有很多共同的配置的,也就是公共部分。

比如入口entry和出口打包文件的output还有loader等等都是公共部分,两个配置文件都需要。

所有我们通常再创造一个文件webpack.common.config.js(这个名字随便命名,你用的时候知道就好了)

webpack.dev.config.js

const { merge } = require("webpack-merge")
const commonConfig = require("./webpack.common.config")

module.exports = merge(commonConfig, {
  mode: "development",
  devServer: {
    hot: true,
    // host: "0.0.0.0",
    // port: 8888,
    // open: true
    // compress: true
  }
})

如上,抽取了公共配置后,dev配置直接使用require引入就好了

然后我们需要用到一个合并插件

npm installwebpack-merge -D

可以看到在代码中,我们使用了这个插件的包的一个merge函数,然后通过这个函数合并了公共配置和当前dev配置。

总结

这些七里八里的配置插件,大部分不需要记,我们知道有这个东西,万一需要查文档用就好了

而且大部分配置我们在vue开发中,脚手架都帮我们搞好了,只是说了解了原理,出现了错误,我们可以快速解决

作业布置

三. 什么是loader?webpack的loader是什么作用?和Plugin有什么区别?

  • loader用来对模块的源代码进行转换,加载文件

    • 比如因为webpack 不知道怎么样去加载css文件,所以我们需要用css-loader来加载css文件

    • 主要通过配置方式来使用loader来加载

      module: {
         rules: [
           {
             // 告诉webpack匹配以.css结尾的文件
             test: /\.css$/,
             // use: [
             //   // 注意顺序,从下往上执行
             //   { loader: "style-loader" },
             //   { loader: "css-loader" }
             // ]
             //简写一: 如果loader只有一个
             // loader: "css-loader"
             //简写二: 多个loader不需要其他属性时,可以直接写loader字符串形式
             // 配置方式一
             use: ["style-loader", "css-loader", "postcss-loader"]
             // 配置方式二
             // use: ["style-loader", "css-loader", {
             //   loader: "postcss-loader",
             //   options: {
             //     postcssOptions: {
             //       plugins: [
             //         "autoprefixer"
             //       ]
             //     }
             //   }
             // }]
           },
           {
             // 告诉webpack匹配以.css结尾的文件
             test: /\.less$/,
             // use: [
             //   // 注意顺序,从下往上执行
             //   { loader: "style-loader" },
             //   { loader: "css-loader" },
             //   { loader: "less-loader" },
             //   { loader: "postcss-loader" }
             // ]
             // 简写
             use: ["style-loader", "css-loader", "less-loader", "postcss-loader"],
           }
         ]
       }
      • loader和plugin的区别
        • loader是用于特定的模块类型(css,vue…)进行解析加载
        • plugin 是用于执行更多广泛的任务,比如打包优化,资源管理,环境变量注入等
          • 常见的插件
            • CleanWebpackPlugin 每次修改了一些配置,重新打包时,帮助我们删除dist文件夹
            • HtmlWebpackPlugin 对index.html进行打包处理,自动在dist文件夹中,生成了一个index.html的文件
            • DefinePlugin 允许在编译时创建配置的全局常量,是一个webpack内置的插件(不需要单独安装)
              • 比如process.env.NODE_ENV 判断当前环境是开发还是生产

四. 什么是babel?babel在开发中是什么作用?

  • Babel是一个工具链,主要用于旧浏览器或者环境中将ECMAScript 2015+代码转换为向后兼容版本的JavaScript (ES6以上的代码转成ES5代码)
  • 作用: 语法转换,源代码转换,箭头函数转换 ,ES6以上的代码转成ES5代码

五.webpack的开发模式和生产模式有什么区别?

  • Mode: development 开发模式
    • 会将process.env.NODE_ENV 的值设置为development
  • Mode: production 生产模式
    • 会将process.env.NODE_ENV 的值设置为production

六. webpack如何开启本地服务器,并且提高页面的更新效率(HMR)?

  • 如何开启本地服务器?

    • 安装webpack-dev-server

      npm install webpack-dev-server -D
      
    • 修改配置文件,启动时加上serve

      "scripts": {
         "serve": "webpack serve --config wk.config.js"
       },
    • 命令 : npm run serve

  • HMR 模块热替换

    • 模块热替换是指在 应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个页面

    • 如何使用HMR

      • 默认情况下,webpack-dev-server已经支持HMR,我们只需要开启即可(默认已经开启);
      • 在不开启HMR的情况下,当我们修改了源代码之后,整个页面会自动刷新,使用的是live reloading;

      在main.js中

      if (module.hot) {
        module.hot.accept("./utils/demo.js", () => {
          console.log("demo更新")
        })
      }

文章作者: 瑾年
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 周东奇 !
免责声明: 本站所发布的一切内容,包括但不限于IT技术资源,网络攻防教程及相应程序等文章仅限用于学习和研究目的:不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。本站部分信息与工具来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如有侵权请邮件(jinnian770@gmail.com)与我们联系处理。
  目录