Webpack基础知识

125 阅读3分钟

Webpack 是什么

1.认识 Webpack

webpack 是静态模块打包器,当 webpack 处理应用程序时,会将所有这些模块打包成一个或多个文件

 import './module.js'
 ​
 require('./module.js')

2.什么是 Webpack

模块

webpack 可以处理 js/css/图片、图标字体等单位

静态

开发过程中存在于本地的 js/css/图片/图标字体等文件,就是静态的

动态的内容,webpack没办法处理,只能处理静态的

Webpack初体验

1.初始化项目

 npm init

2.安装 webpack 需要的包

  npm install --save-dev webpack-cli@3.3.12 webpack@4.44.1

3.配置 webpack

 // 默认webpack.config.js
 const path = require('path')
 ​
 module.exports = {
   entry: './src/index.js',
   output: {
     path: path.resolve(__dirname, 'dist'),
     filename: 'bundle.js'
   }
 }

4.编译并测试

 // package.json
 ​
 // 默认 webpack.config.js
  "webpack": "webpack"
 // 自己指定 webpack.js
  "webpack": "webpack --config webpack.js"
 ​
 // 命令行
 npm run webpack

Webpack核心概念

entry 和 output

1.entry

指定入口文件

单入口

 //webpack.config.js
 entry:'./src/index.js'

多入口

多页面开发,每个页面都有一个js文件,所以需要多入口

 //webpack.config.js
 entry:{
     main:'./src/index.js',
     search:'./src/search.js'
 }

2.output

单出口

  output: {
     // __dirname,node提供,每个模块都会有,意思是当前文件所在目录。
     // path.resolve:方法会把一个路径或路径片段的序列解析为一个绝对路径,这里的意思是把当前目录和dist拼接起来。
     path: path.resolve(__dirname, 'dist'),
     // 指定输出js文件名
     filename: 'bundle.js'
   }

多出口

   output: {
     path: path.resolve(__dirname, 'dist'),
     filename: '[name].js'
   }

loader

1.什么是 loader

loader 让 webpack 能够去处理那些非 js 文件的模块

2.babel-loader

 npm install --save-dev babel-loader@8.1.0

3.安装 Babel

@babel/core是Babel进行转码的核心依赖包

@babel/preset-env 主要作用是对我们所使用的并且目标浏览器中缺失的功能进行代码转换和加载 polyfill,在不进行任何配置的情况下,@babel/preset-env 所包含的插件将支持所有最新的JS特性(ES2015,ES2016等,不包含 stage 阶段),将其转换成ES5代码。

 npm install --save-dev @babel/core@7.11.0 @babel/preset-env@7.11.0
 ​
 // 更详细配置参见官方文档:https://www.webpackjs.com/loaders/
 // 新建.babelrc
 {
     "persets":["@babel/perset-env"]
 }

4.配置 babel-loader

 // webpack.config.js
 module:{
     rules:[
         {
             test:/.js$/,
             // 排除,减少工作量
             exclude:/node_modules/,
             loader:'babel-loader'
         }
     ]
 }

只能转换声明等少数ES6语法。

5.引入 core-js

core-js 和一个自定义的 regenerator runtime 模块,可以模拟完整的 ES2015+ 环境(不包含第4阶段前的提议)。

这意味着可以使用诸如 PromiseWeakMap 之类的新的内置组件、 Array.fromObject.assign 之类的静态方法、Array.prototype.includes 之类的实例方法以及生成器函数(前提是使用了 @babel/plugin-transform-regenerator 插件)。

 // 安装
 npm install --save-dev core-js@3.6.5
 // 源码导入
 import "core-js/stable"

6.打包并测试

 npm run webpack

plugins

1.什么是 plugins

loader 被用于帮助 webpack 处理各种模块,而plugins目的在于解决loader无法实现的其他事

 https://www.webpackjs.com/plugins/

2.安装html-webpack-plugin

该插件将为你生成一个 HTML5 文件, 其中包括使用 script 标签的 body 中的所有 webpack 包

 npm install --save-dev html-webpack-plugin@4.3.0

3.配置 html-webpack-plugin 插件

 // webpack.config.js
 const HtmlWebpackPlugin = require('html-webpack-plugin')
 ​
 plugins: [
     new HtmlWebpackPlugin({
       template: './index.html'
     })
   ]

4.多页面时 html-webpack-plugin 插件的配置

如果你有多个 webpack 入口点, 他们都会在生成的HTML文件中的 script 标签内

 const HtmlWebpackPlugin = require('html-webpack-plugin')
 ​
 plugins: [
     //单入口
     // new HtmlWebpackPlugin({
     //   template: './index.html'
     // })
 ​
     //多入口
     new HtmlWebpackPlugin({
       // 指定模板文件
       template: './index.html',
       // 指定生成文件名
       filename: 'index.html',
       // 指定模板引入的js文件名
       chunks: ['index']
     }),
     new HtmlWebpackPlugin({
       template: './search.html',
       filename: 'search.html',
       chunks: ['search']
     })

5.html-webpack-plugin 插件的其他功能

 new HtmlWebpackPlugin({
   template: './index.html',
   filename: 'index.html',
   chunks: ['index'],
   minify: {
     // 删除 index.html 中的注释
     removeComments: true,
     // 删除 index.html 中的空格
     collapseWhitespace: true,
     // 删除各种 html 标签属性值的双引号
     removeAttributeQuotes: true
   }
 })

处理CSS文件

 // css-loader
 // 帮助webpack识别css模块
 // style-loader
 // 把CSS放在<style></style>通过内联方式加载
 module: {
     rules: [
       {
         //Rule.test 是 Rule.resource.test 的简写。如果你提供了一个 Rule.test 选项,就不能再提供 Rule.resource。匹配正则
         test: /.css$/,
         // loader: 'css-loader',
         // 配置多个loader
         // 从右向左,先通过css-loader识别文件,识别以后再通过style-loader嵌入到html文件中
         use: ['style-loader', 'css-loader']
       }
     ]
   }
 ​
 //------------------------------------------------------------------------------------------------
 // mini-css-extract-plugin
 // 将css提取成一个单独文件,通过<link></link>引入
 // 导入mini-css-extract-plugin
 const MiniCssExtractPlugin = require('mini-css-extract-plugin')
 ​
 module: {
     rules: [
       {
         test: /.css$/,
         // 从右向左,先通过css-loader识别文件,识别以后再通过MiniCssExtractPlugin.loader嵌入到html文件中
         use: [MiniCssExtractPlugin.loader, 'css-loader']
       }
     ]
   },
   plugins: [
     new MiniCssExtractPlugin({
       filename: 'css/[name].css'
     })
   ]

处理图片

使用file-loader 处理css中的图片

如果是外部的资源,是不需要考虑 webpack 的,只有本地的图片才需要被 webpack 处理

 module: {
     rules: [
       {
         test: /.css$/,
         use: [
           {
             loader: MiniCssExtractPlugin.loader,
             options: {
               // MiniCssExtractPlugin.loader 和 file-loader协同处理图片,这里需要把之前指定的css文件夹的文件放到上层目录
               publicPath: '../'
             }
           },
           'css-loader'
         ]
       },
       {
         test: /.(jpg|png|gif)$/,
         use: {
           loader: 'file-loader',
           options: {
             // img文件夹下 本身的名字.本身的扩展名
             name: 'img/[name].[ext]'
           }
         }
       }
     ]
   }

使用html-withimg-loader处理HTML中的图片

底层还是file-loader

 module: {
     rules: [
       {
         test: /.(jpg|png|gif)$/,
         use: {
           loader: 'file-loader',
           options: {
             // img文件夹下 本身的名字.本身的扩展名
             name: 'img/[name].[ext]',
             // file-loader默认按照 ES6 模块导出,关闭
             esModule: false
           }
         }
       },
       {
         test: /.(htm|html)$/,
         loader: 'html-withimg-loader'
       }
     ]
   }

使用file-loader处理JS中的图片

 // index.js
 import img from './img/baidu.png'
 ​
 const imgEI = document.createElement('img')
 imgEI.src = img
 document.body.appendChild(imgEI)
 ​
 //webpack.config.js保持原样

使用url-loader处理图片(推荐使用)

url-loader 功能类似于 file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL(Base64)。

太大的图片不推荐,Base64化以后会储存在js文件中,图片越大,文件越大。比较常用的比如图标字体。

url-loader 底层使用的也是 file-loader ,我们以后可以直接配置 url-loader ,而不用配置 file-loader 处理图片

  {
         test: /.css$/,
         use: [
           {
             loader: MiniCssExtractPlugin.loader,
             options: {
               // MiniCssExtractPlugin.loader 和 url-loader协同处理图片,这里需要吧之前指定的css文件夹下的文件放到上层目录
               publicPath: '../'
             }
           },
           'css-loader'
         ]
       },
       {
         test: /.(jpg|png|gif|jpeg)$/,
         use: {
           loader: 'url-loader',
           options: {
             // img文件夹下 本身的名字.本身的扩展名
             name: 'img/[name].[ext]',
             // 不按照 ES6 模块导出
             esModule: false,
             // 限制,多大体积
             limit: 20000
           }
         }
       }

使用webpack-dev-server搭建开发环境

帮助快速开发

 // npm install --save-dev webpack-dev-server@3.11.0
 // https://www.webpackjs.com/configuration/dev-server/
 // package.json
 // 使用这条命令,不会在硬盘生成dist文件,生成的文件存储在内存
  "dev": "webpack-dev-server --open chrome"

参考:

慕课前端笔记

不容错过的 Babel7 知识

扩展:

2020年了,再不会webpack敲得代码就不香了(近万字实战)