webpack的使用以及语法介绍

344 阅读6分钟

- webpack基本概念和作用

  • 现代 javascript 应用程序的 静态模块打包器 (module bundler)
  1. 静态: 文件资源
  2. 模块: node环境, 引入文件, 遵守模块化语法
  3. 开发完项目, 可以用node+webpack来分析, 翻译, 压缩, 打包
  4. ==减小代码包体积, 让浏览器更快速打开网页==
  • 除了合并代码, 还可以翻译压缩代码
    • less/sass -> css
    • ES6/7/8 -> ES5
    • html/css/js -> 压缩合并

- webpack使用步骤

  1. webpack依赖Node环境,npm或yarn等模块管理工具
  2. 创建webpack基础使用文件夹
  3. 下载yarn webpack工程模块化工具,打包 下载yarn下载地址: yarn.bootcss.com/docs/instal…
下载地址: <https://yarn.bootcss.com/docs/install/#windows-stable>
  1. ==建议不要安装到中文路径下==
  2. ==建议和node安装到一个盘符下==
  3. mac - 通过命令安装(也可还用npm)
sudo npm i -g yarn

如果上面不行, 试试这个

curl -o- -L https://yarnpkg.com/install.sh | bash

使用yarn:

与npm类似, 可以试试, 新建一个空白文件夹, 执行以下命令尝试一下

# 1. 初始化, 得到package.json文件(终端路径所在文件夹下)
yarn init
# 类似: npm init

# 2. 添加依赖(下包)
# 语法: yarn add [package]

# 3. 移除包
# 语法: yarn remove [package]
             
# 4. 安装项目全部依赖(一般拿到别人的项目时, 缺少node_modules)          
yarn
# 会根据当前项目package.json记录的包名和版本, 全部下载到当前工程中
# 类似: npm i

# 5. 全局
# 安装: yarn global add [package]
# 卸载: yarn global remove [package]
# 注意: global一定在add左边

#6.下载vue全局
yarn global add @vue/cli

#7.在package.json中, 配置scripts(自定义命令)
scripts: {
	"build": "webpack"
}
  • webpack-插件-自动生成html文件
  1. 自动生成html文件
  2. 自动引入打包后文件 html-webpack-plugin插件文档 下载插件
yarn add html-webpack-plugin@5.3.1  -D

webpack.config.js配置

// 引入自动生成 html 的插件
const HtmlWebpackPlugin = require('html-webpack-plugin') 

module.exports = {
    // ...省略其他代码
    plugins: [
        new HtmlWebpackPlugin({
            // 以此为基准生成打包后html文件
            template: './public/index.html' 
        })
    ]
}
  • webpack-加载器-处理css文件问题
  1. style-loader文档
  2. css-loader文档 安装依赖
yarn add css-loader@5.2.1 style-loader@2.0.0  -D

webpack.config.js 配置

module.exports = {
    // ...其他代码
    module: { // 如何处理项目中不同模块文件
        rules: [ // 规则
          {
            test: /\.css$/, // 匹配所有的css文件
            // use数组里从右向左运行
            // 先用 css-loader 让webpack能够识别 css 文件的内容并打包
            // 再用 style-loader 将样式, 把css插入到dom中
            use: [ "style-loader", "css-loader"]
          }
        ]
    }
}

  1. ==在main.js引入index.css==
import "./css/index.css"
  • 配置完之后运行打包命令:
yarn build 
  • webpack-加载器-处理less文件
  1. less-loader文档
  2. 引入到main.js中
yarn add less@4.1.1 less-loader@8.1.0 -D

webpack.config.js 配置

module: {
  rules: [ 
    // ...省略其他
    {
    	test: /\.less$/, // 匹配.less结尾文件
    	// 使用less-loader, 让webpack处理less文件, 内置还会用less模块, 翻译less代码成css代码
        use: [ "style-loader", "css-loader", 'less-loader']
    }
  ]
}
  • 对图片有哪两种处理方案
  • webpack-加载器-处理图片文件
  1. webpack5内置处理方案, 只需要填入配置即可
  2. asset module资源模块文档
module: {
    rules: [ 
        // ...省略其他
        {
            test: /\.(png|jpg|gif|jpeg)$/i, // 匹配图片文件
            type: 'asset' // 在导出一个 data URI 和一个单独的文件之间自动选择
        }
    ]
}

asset模块区分

module: {
    rules: [ 
        // ...省略其他
        {
            test: /\.(png|jpg|gif|jpeg)$/i, // 匹配图片文件
            type: 'asset' // 在导出一个 data URI 和一个单独的文件之间自动选择
            // 小于8kb的, 转成data URI(图片转成base64字符串打包进js中)
            // 大于8kb的, 直接复制文件到dist目录下(因为转base64会体积增30%)
        }
    ]
}

  1. 默认8kb以下图片, 转成base64字符串打包进js中, 减少网络请求次数
  2. 超过8kb的图片, 直接复制到dist下, 转base64会增加30%体积
  • webpack-加载器-处理字体文件 在main.js引入iconfont.css
// 引入字体图标文件
import './assets/fonts/iconfont.css'

在public/index.html使用字体图标样式

<i class="iconfont icon-weixin"></i>

配置

  1. webpack5, 用asset module技术
  2. webpack.config.js
{ 
    test: /\.(eot|svg|ttf|woff|woff2)$/,
    type: 'asset/resource',  // 当做静态资源直接复制文件
    generator: {
    	filename: 'font/[name].[hash:6][ext]' // 放到dist/font文件       夹, 文件名格式如左
    }
}

  • webpack-加载器-处理高版本js语法
  1. webpack, 对高版本js语法降级
  2. babel编译器=>用于处理高版本js语法的兼容性babel官网
  3. webpack配合babel-loader 对js语法做处理 babel-loader文档 src/main.js - 编写箭头函数
const fn = () => { // 高级语法
  console.log("你好babel");
}
console.log(fn) // 一定打印函数, 才会被webpack把"函数体"打包起来

安装包

yarn add -D babel-loader@8.2.2 @babel/core@7.13.15 @babel/preset-env@7.13.15

webpack.config.js 配置规则

module: {
    rules: [
        {
            test: /\.js$/, // 匹配js结尾文件
            exclude: /(node_modules|bower_components)/, // 不转换这2个文件夹里的js
            use: { 
                loader: 'babel-loader', // 使用加载器-处理
                options: {
                    presets: ['@babel/preset-env'] // 预设:转码规则(用bable开发环境本来预设的)
                }
            }
        }
    ]
}

打包后观察dist/的js文件, 自动变成普通函数

  • 总结: 只要找到对应的loader加载器, 就能让webpack处理不同类型文件

  • 效果:

  1. src并列处, 生成dist目录和main.js文件
  2. 查看main.js文件, 是打包压缩后的代码
  3. css代码被打包进了dist/bundle.js中
  4. 运行时, css代码插入到html的style标签中
  • 下载包可以用到的几个命令:
  1. 方式一:安装nrm全局包(得到nrm命令)
  2. 作用: 切换npm包下载地址:
// 全局下载 - 得到nrm命令
npm i nrm -g
// 查看有哪些可用的下载地址
nrm ls

// 切换npm下载地址
nrm use taobao

// 查看效果是否成功
npm config list

// 查看registry下载地址是否变化
  1. 方式二:安装cnpm全局包(得到cnpm命令)
  2. 作用:以后用cnpm来下包
// 全局下载 cnpm - 得到cnpm命令
npm i cnpm -g

// 可以用cnpm 代替 npm使用
// 下包 cnpm i 包名

  • 通常情况下使用yarn即可
  • 下载webpack-dev-server, 启动一个开发服务器, 用于快速开发应用程序

webpack-dev-server文档 下载包

yarn add webpack-dev-server@3.11.2 -D

配置自定义命令serve

scripts: {
	"build": "webpack",
	"serve": "webpack serve"
}

运行命令-启动webpack开发服务器

yarn serve
#或者 npm run serve
  1. 启动一个web服务器和端口, 在浏览器访问查看
  2. 效果: 以后改src下的代码, 自动打包更新到浏览器上 webpack-dev-server配置文档 webpack.config.js中添加服务器配置
module.exports = {
    // ...其他配置
    devServer: {
      port: 3000, // 端口号
      open: true // 启动后自动打开浏览器
    }
}

准备一个后端web服务, 把dist放进去, 暴露成静态资源目录供别人访问

// 准备一个node+express的web服务, 可以部署和启动在一个接入外网的电脑上, 别人都可以访问

const express = require('express')
const app = express()

// . 当前文件所在文件夹
// / 打开文件夹
// ./当前当前文件夹(也可以省略)
app.use(express.static('./dist'))

app.listen(4005)

- 打包优化:

1. 打包优化- yarn build生成 dist目录

  1. 双击无法打开, 默认打包出来的路径是绝对路径 => 服务器环境
  • 方法1:
  1. 修改配置允许dist目录双击打开
  2. 修改打包路径为相对路径 在vue.config.js文件夹中追加配置
module.exports = {
//希望打包时 以相对路径
  publicPath: './'
}

  • 方法2:
  1. dist根目录VScode打开
  2. VScode中下载live server 插件
  • 这样就可以查看自己打包后的代码是否可以运行了

2.打包优化-配置路由懒加载

  1. 用户第一次点进来, 加载了所有组件, 希望 他看到了哪个组件, 加载对应的组件
  2. 首屏加载更快,只需要加载首屏对应的登录组件即可, 用户体验更好 在路由页面把普通的路由引入方式换出以下:
const Login = () => import('@/views/Login')
const Reg = () => import('@/views/Reg')
const Layout = () => import('@/views/Layout')
const Home = () => import('@/views/Home')
const ArtCategory = () => import('@/views/ArtCategory')
const ArtList = () => import('@/views/ArtList')
const UserInfo = () => import('@/views/UserInfo')
const ChangeAvatar = () => import('@/views/ChangeAvatar')
const ResetPwd = () => import('@/views/ResetPwd')

打包优化-打包移除 console控制台打印

下载插件

`yarn add terser-webpack-plugin -D`

vue.config.js文件中配置

module.exports = {
  chainWebpack: (config) => {
    config.optimization.minimizer('terser').tap((args) => {
      args[0].terserOptions.compress.drop_console = true
      return args
    })
  }
}

打包优化-移除第三方包引入cdn地址

  • cdn 在线链接
// 获取当前的打包环境
const env = process.env.NODE_ENV
// 打包排除项
let externals = {}

// 根据打包环境,动态设置打包排除项
if (env === 'production') {
  externals = {
    // import 时的包名称: window 全局的成员名称
    vue: 'Vue',
    'vue-router': 'VueRouter',
    vuex: 'Vuex',
    axios: 'axios',
    dayjs: 'dayjs',
    echarts: 'echarts',
    'element-ui': 'ELEMENT',
    'vue-quill-editor': 'VueQuillEditor'
  }
}

module.exports = {
  publicPath: './',
  // 增强 vue-cli 的 webpack 配置项
  configureWebpack: {
    // 打包优化
    //配置排除项后下载的包就会走cnd
    //一旦设置了这些排除项后,webpack就不会把这个包打进项目
    externals
  },
    // 移除控制台打印
   chainWebpack: (config) => {
    config.optimization.minimizer('terser').tap((args) => {
      args[0].terserOptions.compress.drop_console = true
      return args
    })
  } 
}
<!DOCTYPE html>
<html lang="">
  <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">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.core.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.snow.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.bubble.css">
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
     <!-- 如果是开发环境 不要加载这些cdn资源, 如果是生产环境再加载这些资源 -->
    <% if(htmlWebpackPlugin.options.env === 'production') { %>    
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-router@3.5.2/dist/vue-router.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuex@3.6.2/dist/vuex.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.21.3/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/dayjs@1.10.6/dayjs.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.2.0/dist/echarts.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/element-ui@2.15.5/lib/index.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/quill@1.3.7/dist/quill.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue-quill-editor@3.0.6/dist/vue-quill-editor.js"></script>
    <% } %>
    <!-- built files will be auto injected -->
  </body>
</html>