1.2 webpack 快速上手

快速上手:

一. 初始化项目(取名字的时候一定不要取工具的名字) npm init -y

二. 安装webpackc

webpack 安装的两种方式:

  1. 运行npm install --global webpack全局安装webpack,这样就能在全局使用webpack命令【不建议】
  2. 在项目根目录中运行npm install webpack webpack-cli --save-dev安准到项目依赖中【建议在本地安装】

三. webpack 基础使用

  1. 参考 webpack-study 文件夹创建对应的目录,或者看下官网的入门学习。
  2. 创建 webpack.config.js 文件
  const path = require('path');

  module.exports = {
    entry: './src/index.js', // 入口文件
    output: { // 出口
      filename: 'bundle.js', // 打包后的文件名
      path: path.resolve(__dirname, 'dist') // 打包后的文件路径
    }
  };
  1. 在根目录运行npx webpack命令,之后就能看到打包好的 bundle.js 文件
  2. 使用 npm 命令来打包

    1. 在 package.json 文件中的 "scripts" 对象中,添加 "build": "webpack"

    2. 在根目录运行npm run build命令,等待完成打包

到此为止,我们要看到每次修改后的页面,都必须要先打包,再刷新浏览器,比较繁琐,此时就需要 模块热更新。

webpack-dev-server

  1. 安装到本地开发依赖:运行npm i webpack-dev-server -D
  2. 在 package.json 文件中设置
      "scripts": {
        "dev": "webpack-dev-server"
      },
    
  3. 运行npm run dev
  • 默认会开启 http://localhost:8080/ ,在浏览器中直接访问就行,
  • 构建的出口文件默认在 / 根路径,所有要检查 index.html 文件中对打包文件的引用地址是否正确
- <script src="bundle.js"></script>
+ <script src="/bundle.js"></script>
  • webpack-dev-server 帮我们打包生成的 bundle.js 文件,并没有存放到实际的物理磁盘上,而是直接托管到了电脑内存中,所以,我们在项目根目录中,根本找不到这个打包好的 bundle.js。我们可以认为:webpack-dev-server 把打包好的文件以一种虚拟的形式,托管到了项目的根目录中,虽然我们看不到它,但是我们可以认为,和 dist、src、node_modules 平级,有一个看不见的文件,叫做 bundle.js
  1. 注意:这里要考虑兼容问题,2020/11/20
  • 建议使用版本
```js
  // package.json 文件中
  "devDependencies": {
    //省略其他配置
    "webpack": "^5.6.0",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  }
```
- 更多兼容问题,只能百度,或者各种尝试了。

webpack-dev-server 其它设置

  1. 打包构建成功之后自动在浏览器中打开页面
  • 设置 package.json 文件:"scripts": {"dev": "webpack-dev-server --open"}
  1. 设置端口号,将默认的 8080 端口改成 3000
  • package.json 文件:"scripts": {"dev": "webpack-dev-server --port 3000"}
  1. 默认进入首页,而不是根目录
  • package.json 文件:"scripts": {"dev": "webpack-dev-server --contentBase dist"}
  • dist 是我的 index.html 所在的文件,当然也可以是 src 等。
  1. 模块热更新(HMR:hot module replacement)
  • package.json 文件:"scripts": {"dev": "webpack-dev-server --hot"}
  1. 以上功能连写
  • webpack-dev-server --open --port 3000 --contentBase dist --hot
  1. --open、--port 3000、--contentBase dist、--hot,也可以移植到 webpack.config.js 文件中
const webpack = require('webpack'); // 启用热更新 的 第2步
module.exports = {
   // ...此处省略
    devServer: { // 这是配置 dev-server 命令参数的第二种形式,相对来说,这种方式麻烦一些
      open: true, // 打开浏览器
      port: 3000, // 设置端口
      contentBase: 'dist', // 指定托管的根目录
      hot: true // 启用热更新 的 第1步
    },
    plugins: [ // 配置插件的节点
      new webpack.HotModuleReplacementPlugin() // new 一个热更新的模块对象,启用热更新 的 第3步
    ]
}

此时 package.json 中只需要 "scripts": {"start": "webpack-dev-server"}

注意 这里我写了 "start", 启动项目的命令就是 npm run start,而之前用的变量名为 "dev",响应的就是npm run dev,当然也可以是其它英文单词,不过习惯性的用 "start""dev"

各种 loader(加载器)

webpack,默认只能打包处理 js 类型的文件,无法处理其他非 js 类型的文件。

如果要处理非 js 类型的文件,我们需要安装一些 合适的 第三方加载器(loader)。

安装使用说明

  1. 安装npm install xxx-loader
  2. 打开 webpack.config.js 文件,新增一个配置节点 module,在 module 对象上有个 rules 属性,rules 是个数组,存放了所有第三方文件的匹配和处理规则
  • test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
  • use 属性,表示进行转换时,应该使用哪个 loader。
  1. webpack 处理第三方文件的过程:

    1. 发想要处理的文件不是第三方文件,然后去配置文件中,查找有没有对应的第三方 loader 规则

    2. 如果能找到对应的规则,就会调用对应的 loader 处理这种文件的规则

    3. 在调用 loader 的时候,是从后往前调用的(use: ["style-loader", "css-loader"], 先调用"css-loader",再调用"style-loader")

    4. 当最后一个 loader 调用完毕,会把处理结果,直接交给 webpack 进行打包合并,最终输出到 bundle.js 中

举例

  • .css文件:npm install style-loader css-loader -D
  module: { // 这个节点,用于配置所有第三方模块 加载器
    rules: [ // 所有第三方模块的匹配规则
      {
        test: /\.css$/, use: ["style-loader", "css-loader"] // 配置处理 .css 文件的第三方 loader 规则
      }
    ]
  }
  • .less 文件:npm install less less-loader -D
  module: {
    rules: [
      {
        test: /\.less$/, use: ["style-loader", "css-loader", "less-loader"]
      }
    ]
  }
  • .sass 文件:npm install node-sass sass-loader -D
  module: {
    rules: [
      {
        test: /\.scss$/, use: ["style-loader", "css-loader", "sass-loader"]
      }
    ]
  }
  • .ts 文件:npm install --save-dev ts-loader

    没验证过

  module: {
    rules: [
      {
        test: /\.ts$/, use: 'ts-loader'
      }
    ]
  }
  • .jsx 文件:npm install --save-dev babel-core babel-preset-es2015 babel-loader jsx-loader

    没验证过

  module: {
    rules: [
      {test: /\.js$/, loader: "babel", exclude: /node_modules/},
      {test: /\.jsx$/, loader: "jsx-loader"}
    ]
  }
  • 在react中启用jsx语法 (参考 下文 Babel )

    1. 运行npm install babel-core babel-loader babel-plugin-transform-runtime -D
    2. 运行npm install abel-preset-env babel-preset-stage-0 -D
    3. 能够识别转换 jsx 语法的包:npm install babel-preset-react -D
    4. 添加.babelrc配置文件
        {
          "presets": ["env", "stage-0", "react"],
          "plugins": ["transform-runtime"]
        }
      
  • 图片 文件:npm install url-loader file-loader -D

  module: {
    rules: [
      // test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader'
      test: /\.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=240&name=[hash:8]-[name].[ext]'
    ]
  }
  • 打包后默认会改变图片的名字,并转成 base64 字符串

    1. 如何有选择的转成 base64 :

      limit 给点的值是图片的大小,单位是 byte,

      当引用的图片大小 大于或等于 给定的值,则不会被转换位base64格式的字符串,

      如果 小于 给点的值,则会被转成base64格式的字符串

      作用是让小图片转成 base64 ,而大图片则不需要

    2. 如何不改变名字:

      name=[hash:8]-[name].[ext]

      [name]代表图片之前叫什么名字,打包过后依旧叫什么

      [ext] 代表图片之前是什么尾缀,打包过后依旧是什么

      [hash:8]- 每一张图片前面增加一段hash值,防止重命名,hash值是32位的,:8代表截取前8位,不能超过32位

  • 字体文件

  module: {
    rules: [
      test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader'
    ]
  }

Babel javaScript 语法编译器

在 webpack 中,默认只能处理一部分 ES6 的新语法,一些更高级的ES6语法或者 ES7语法,webpack 是处理不了的。

这时候,就需要借助于第三方的 loader,来帮助 webpack 处理这些高级的语法,当第三方 loader 把高级语法转换为低级的语法,

会把结果交给 webpack 去打包到 bundle.js 中。

通过 Babel,可以帮助我们将高级的语法转换为低级的语法

  1. 在 webpack 中,可以运行如下两套命令,安装两套包,去暗转 Babel 相关的 loader 功能

    1.1 第一套包:npm i babel-core babel-loader babel-plugin-transform-runtime -D

    1.2 第二套包:npm i babel-core babel-preset-env babel-preset-stage-0 -D

  2. 打开 webpack 的配置文件,在 module 节点下的 rules 数组中,添加一个新的匹配规则

    2.1 {test:/.js$/, use: 'babel-loader', exclude: /node_modules/}

    2.2 在配置 babel-loader 规则的时候,必须把 node_modules 目录,通过 exclude 选项排除掉,原因有俩:

    2.2.1 如果不排除 node_modules,则 Babel 会把 node_modules 中所有的第三方 Js 文件,都打包编译,这样会非常消耗 CPU,同时打包速度非常慢

    2.2.2 哪怕,最终 Babel 把所有 node_modules 中的Js转换完毕了,但是项目也无法正常运行!

  3. 在项目的根目录中,新建一个叫做 .babelrc 的 Babel 配置文件,这个配置文件,属于JSON格式,所以在写 .babelrc 配置的时候,

    必须符合JSON语法规范(不能写注释,字符串必须用双引号

    3.1 在 .babelrc 写如下的配置:

    "presets" 可以理解成:语法

    "plugins" 插件,这里指 babel 的插件

    {
      "presets": ["env", "stage-0"],
      "plugins": ["transform-runtime"]
    }
    
  4. 了解:目前,我们安装的 babel-preset-env,是比较新的ES语法,之前,我们安装的是 babel-preset-es2015 (ES6),现在,出了

    一个更新的语法插件,叫做 babel-preset-env,它包含了所有的 和 ES***相关的语法