前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2022-webpack5实战教程

2022-webpack5实战教程

原创
作者头像
gogo2027
发布2022-10-17 16:06:23
8290
发布2022-10-17 16:06:23
举报

前言

手摸手教你如何打包,让你在动手的实践过程中感受webpack。

在动手之前,你可先简单了解一下webpack的概念

每一小结都有对应的分支,方便大家学习

webpack版本:5.58.1

入门

新建一个目录,初始化npm

npm init

接下来安装webpackwebpack-cli两个包

npm i -D webpack webpack-cli

默认配置

新建一个文件夹src ,里面新建一个main.js,写一点测试代码

console.log("webpack")

在package.json中scripts中添加新的命令

代码语言:javascript
复制
"scripts": {
  "build": "webpack ./src/main.js"
},

执行打包命令npm run build

此时如果生成了一个dist文件夹,并且内部含有main.js说明已经打包成功了

这个例子只是webpack自己默认的配置,下面我们要实现更加丰富的自定义配置

自定义配置

新建一个build文件夹,里面新建一个webpack.config.js

代码语言:javascript
复制
const path = require('path');

module.exports = {
  mode:'development', // 开发模式
  entry: path.resolve(__dirname,'../src/main.js'), // 入口文件
  output: {
      filename: 'output.js', // 打包后的文件名称
      path: path.resolve(__dirname,'../dist') // 打包后的目录
  }
}

更改打包命令

代码语言:javascript
复制
{
  // ...
  "scripts": {
    "build": "webpack --config build/webpack.config.js"
  },
}

然后执行 npm run build,会得到如下结果

在这里插入图片描述
在这里插入图片描述

其中main.js是我们第一次打包遗留的。

js已经打包好了,接下来我们要做的就是将js引入到html文件中

添加js到html文件

我们需要html-webpack-plugin来帮我们完成这件事情

npm i -D html-webpack-plugin

新建一个与build同级的文件夹public,里面新建一个index.html

配置如下

代码语言:javascript
复制
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  mode:'development', // 开发模式
  entry: path.resolve(__dirname,'../src/main.js'), // 入口文件
  output: {
      filename: '[name].[hash:8].js', // [name] 指entry属性名字, 默认为main
      path: path.resolve(__dirname,'../dist') // 打包后的目录
  },
  plugins:[
    new HtmlWebpackPlugin({
      // 选取一个html作为模版,在dist目录下会生成一个相同的html,之后将打包好的js注入到该html文件
      template: path.resolve(__dirname,'../public/index.html') 
    })
  ]
}

打包成功之后,查看dist目录下的index.html文件是否引用了打包之后的js

多文件如何注入到html
  1. 多个入口文件,注入到同一个html文件中

这种情形我们只需添加入口就OK了,html-webpack-plugin插件会自动把所有打包好的js注入到html里

代码语言:javascript
复制
module.exports = {
  // ...
  entry: {
    main: path.resolve(__dirname,'../src/main.js'),
    share: path.resolve(__dirname,'../src/share.js')
  }
}
  1. 多个入口文件,根据不同需求注入到不同的html文件

我们可以通过生成多个html-webpack-plugin实例来解决这个问题

代码语言:javascript
复制
module.exports = {
 // ...
  plugins:[
    new HtmlWebpackPlugin({
      // 选取一个html作为模版,在dist目录下会生成一个相同的html,之后将打包好的js注入到该html文件
      template: path.resolve(__dirname,'../public/index.html'),
      filename: 'index.html',
      chunks: ['main'] // 配置将哪些文件注入到该html文件,为[]在代表不注入js,若无该属性,默认注入所有js
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname,'../public/share.html'),
      filename: 'share.html',
      chunks: ['share']
    })
  ] 
}

打包前清空dist目录

相信大家也发现了,dist目录下的文件越来越多,下面我们就来解决这个问题

我们需要clean-webpack-plugin来帮我们完成这件事情

npm i -D clean-webpack-plugin

代码语言:javascript
复制
// 其余配置同上
const { CleanWebpackPlugin } = require('clean-webpack-plugin')

module.exports = {
   plugins:[
    // ...
    new CleanWebpackPlugin()
  ] 
}

经掘友提醒,webpack5有新增清空dist目录的方式,在output增加clean字段,现补充在下面

代码语言:javascript
复制
module.exports = {
  // ...
  output: {
      filename: '[name].[hash:8].js', // [name] 指entry属性名字, 默认为main
      path: path.resolve(__dirname,'../dist'), // 打包后的目录
      clean: true
  },
}

将css以style标签的方式注入到html

我们的入口文件是js,所以我们在入口js中引入我们的css文件

代码语言:javascript
复制
// main.js
import "../static/css/base.css"
import "../static/css/color.scss"
import "../static/css/fontsize.less"

console.log("webpack")

我们需要一些loader来解析我们的css文件

npm i -D style-loader css-loader

如果使用less来构建样式,则需要安装

npm i -D less less-loader

如果使用scss来构建样式,则需要安装

npm i -D node-sass sass-loader

配置文件如下

代码语言:javascript
复制
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"] // 从右向左开始解析
      },
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"] // 此外还需要安装node-sass(sass也行)
      },
      {
        test:/\.less$/,
        use:['style-loader','css-loader','less-loader'] // 此外还需要安装less模块
      }
    ]
  }
}

打包之后在浏览器中打开html文件,就能看见我们注入的css

在这里插入图片描述
在这里插入图片描述

为css添加浏览器前缀

为了适配更多的浏览器样式我们需要给css加上前缀

我们需要postcss-loader以及autoprefixer来帮我们完成这件事情

参考webpack视频讲解:进入学习

引入autoprefixer方式有两种

  1. postcss.config.js引入(推荐)

**项目根目**录下创建postcss.config.js,配置如下

代码语言:javascript
复制
module.exports = {
  plugins: [
    require('autoprefixer')
  ]
}

然后直接在webpack.config.js中引入

代码语言:javascript
复制
module.exports = {
  // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader", "postcss-loader"] // 从右向左开始解析
      },
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"] // 此外还需要安装node-sass(sass也行)
      },
      {
        test:/\.less$/,
        use:['style-loader','css-loader', "postcss-loader", 'less-loader'] // 此外还需要安装less模块
      }
    ]
  } 
}
  1. 直接在webpack.config.js配置
代码语言:javascript
复制
moudule.exports = {
 // ...
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader", {
          loader: "postcss-loader",
          options: {
            postcssOptions: {
              plugins: [
                ['autoprefixer']
              ]
            }
          }
        }] // 从右向左开始解析
      },
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", {
          loader: "postcss-loader",
          options: {
            postcssOptions: {
              plugins: [
                ['autoprefixer']
              ]
            }
          }
        }, "sass-loader"] // 此外还需要安装node-sass(sass也行)
      },
      {
        test:/\.less$/,
        use:['style-loader','css-loader', {
          loader: "postcss-loader",
          options: {
            postcssOptions: {
              plugins: [
                ['autoprefixer']
              ]
            }
          }
        }, 'less-loader'] // 此外还需要安装less模块
      }
    ]
  } 
}

完成上述配置之后,我们发现css并未成功加上前缀。这里我们还要进行一步操作,那就是配置package.json,在package.json中添加如下配置

代码语言:javascript
复制
{
 // ...
"browserslist": [
    "defaults",
    "not ie < 11",
    "last 2 versions",
    "> 1%",
    "iOS 7",
    "last 3 iOS versions"
  ]
}

外链引入css文件

上述我们通过style标签的方式加载我们的样式,但如果css文件过多就显得很混乱。

我们需要mini-css-extract-plugin帮我们实现

npm i -D mini-css-extract-plugin

代码语言:javascript
复制
// 其余配置保持不变
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  // ...
  plugins: [
    // ...
    new MiniCssExtractPlugin({
      filename: "[name].[hash].css",
    })
  ],
    module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"] // 从右向左开始解析
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", {
          loader: "postcss-loader",
          options: {
            postcssOptions: {
              plugins: [
                ['autoprefixer']
              ]
            }
          }
        }, "sass-loader"] // 此外还需要安装node-sass(sass也行)
      },
      {
        test:/\.less$/,
        use:[MiniCssExtractPlugin.loader,'css-loader', "postcss-loader", 'less-loader'] // 此外还需要安装less模块
      }
    ]
  }
}

不过通过这种方式会将所有的css合并到一个css文件里,如果想要拆分就只有用其他办法里,网上看别人用的是extract-text-webpack-plugin,不过当我去npm官网看时。

在这里插入图片描述
在这里插入图片描述

所以这里就先不讨论拆分css了

图片处理

css与js中图片处理只需添加如下配置就行

代码语言:javascript
复制
module.exports = {
    // ...
  module: {
    rules: [
        // ...
      {
        test: /\.(jpe?g|png|gif)$/i,
        type: "asset",
        generator: {
          filename: 'static/[name].[hash].[ext]'
        }
      },
    ]
  }
}

如果需要处理html中的图片则需要用到html-loader

npm i -D html-loader

配置如下

代码语言:javascript
复制
module.exports = {
    // ...
  module: {
    rules: [
        // ...
      {
        test: /\.html$/i,
        loader: "html-loader"
      },
    ]
  }
}

如果需要配置更多的资源文件,请参考资源模块

转义js文件

为了使我们的js代码兼容更多的环境我们需要转义我们的js文件

npm i -D babel-loader @babel/preset-env @babel/core core-js

代码语言:javascript
复制
module.expors = {
  // ...
  module: {
    rules: [
      // ...
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              [
                '@babel/preset-env',
                {
                  useBuiltIns: 'usage',
                  corejs: {
                    //core-js的版本
                    version: 3
                  },
                  //需要兼容的浏览器
                  targets: {
                    chrome: '60',
                    firefox: '60',
                    ie: '9',
                    safari: '10',
                    edge: '17'
                  }
                }
              ]
            ],
          }
        },
        exclude: /node_modules/
      }
    ]
  }
}

babel-loader负责将ES6/7/8等语法转换为ES5语法

core-js负责将新的api进行转化,例如promise、Generator、Set、Maps、Proxy等

进阶

搭建Vue开发环境

Vue文件处理

首先安装必要依赖

npm i -D vue-loader vue-template-compiler vue-style-loader

npm i -S vue

vue-loader 用于解析.vue文件

vue-template-compiler 用于编译模板

vue-style-loader 解析样式

代码语言:javascript
复制
const vueLoaderPlugin = require('vue-loader/lib/plugin')
module.exports = {
  // ...
  module:{
    rules:[
      // 这一个loader必须放在最前面
      {
        test:/\.vue$/,
        use:['vue-loader']
      }
      // ...
    ]
  },
  resolve:{
    // 设置路径别名
    alias:{
      'vue$':'vue/dist/vue.runtime.esm.js',
      '@':path.resolve(__dirname,'../src')
    },
    // 尝试按顺序解析这些后缀名。
    // 如果有多个文件有相同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。
    extensions:['*','.js','.json','.vue']
  },
  plugins:[
    new vueLoaderPlugin()
  ]
}
热更新配置

我们需要使用webpack-dev-server来启动一个本地服务并且配置热更新

npm i -D webpack-dev-server

配置如下

代码语言:javascript
复制
const Webpack = require('webpack')
module.exports = {
  // ...
  devServer:{
    port:3000,
    hot:true
  },
  plugins:[
    new Webpack.HotModuleReplacementPlugin()
  ]
}

配置打包命令

代码语言:javascript
复制
"scripts": {
  // ...
  "dev": "webpack-dev-server --config build/webpack.config.js --open"
},

添加 --open可自动打开 http://localhost:3000页面

接下来写几行代码进行测试,先修改我们的main.js

代码语言:javascript
复制
// main.js
import Vue from 'vue'
import App from './App.vue'

new Vue({
  render: h => h(App)
}).$mount('#app')

新建一个App.vue文件

代码语言:html
复制
<template>
  <div>
    {{msg}}
  </div>
</template>

<script>
export default {  data() {    return {      msg: "webpack vue"
    }  }}
</script>

<style lang='scss' scoped>
div {  color: aquamarine;  display: flex;}
</style>

修改原来的index.html

代码语言:html
复制
<!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>webpack</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

最后执行npm run dev

区分开发环境和生产环境

development(开发环境)production(生产环境) 这两个环境下的构建目标存在着巨大差异。在开发环境中,我们需要:强大的 source map 和一个有着 live reloading(实时重新加载) 或 hot module replacement(热模块替换) 能力的 localhost server。而生产环境目标则转移至其他方面,关注点在于压缩 bundle、更轻量的 source map、资源优化等,通过这些优化方式改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。

我们在原来webpack.config.js的基础上再新增两个文件webpack.prod.jswebpack.dev.js

这里我们需要使用webpack-merge帮我们merge代码

npm i -D webpack-merge

代码语言:javascript
复制
// webpack.dev.js
const { merge } = require('webpack-merge');
const common = require('./webpack.config.js')

module.exports = merge(common, {
  mode: 'development',
  devtool: 'inline-source-map',
  devServer:{
    port:3000,
    hot:true
  }
});
代码语言:javascript
复制
// webpack.prod.js
const { merge } = require('webpack-merge');
const common = require('./webpack.config.js');

module.exports = merge(common, {
  mode: 'production',
});

原先的webpack.config.js也需要做出修改,我们只需要删除modedevserver字段就行了

最后修改package.json中的scripts命令

代码语言:javascript
复制
"scripts": {
    "build": "webpack --config build/webpack.prod.js",
    "dev": "webpack-dev-server --config build/webpack.dev.js --open"
  },

开发环境运行npm run dev,打包npm run build

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 入门
    • 默认配置
      • 自定义配置
        • 添加js到html文件
          • 多文件如何注入到html
        • 打包前清空dist目录
          • 将css以style标签的方式注入到html
            • 为css添加浏览器前缀
              • 外链引入css文件
                • 图片处理
                  • 转义js文件
                  • 进阶
                    • 搭建Vue开发环境
                      • Vue文件处理
                      • 热更新配置
                    • 区分开发环境和生产环境
                    相关产品与服务
                    图片处理
                    图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档