webpack 学习之路

webpack的几个核心属性

一、entry
指定入口文件,webpack将根据入口文件来建立依赖关系从而进行打包构建

entry分为单入口和多入口

单入口
 entry: "./src/main.js",
多入口则以对象的形式
entry:{
    index:"./src/main.js",
    util:"./src/util/index.js",
    ...
}

二、output
打包后的输出

    output: {
        //所有文件的输出路径,__dirname: nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"),//绝对路径
        //最终产物的文件名,可以指定 也可以使用[name]占位 这样的话就会使用入口文件的名字,多入口的时候必须以占位的形式
        filename: "bundle.js",
        //代码块的文件名
        chunkFilename:"[name].chunk.js",
        clean:true //自动删除上次打包的结果
    },

三、loader
webpack原生只支持解析js和json文件,而在我们日常开发中除了这两种文件还有其他的如 css less scss vue ts jsx 图片 音视频等等种类的文件,loader就是用来解析这类文件将他们转成webpack可解析的格式。loader是一个函数 接收源文件为参数 最终输出一个webpack认识的东西。
下面是一些常见的loader


image.png

webpack本身是单线程的模式去打包构建的 thread-loader可以让webpack多进程打包 从而加快打包速度

loader语法

module: {
        rules: [
    //rules是一个数组里面可以配置多个loader,每个对象表示对一个loader的描述
          {
//当前loader对哪些文件生效 ,是一个正则匹配规则
          test:'',
          use:[]
//use里可以放置多个loader,
//执行顺序:从右到左或者从下到上,最末尾的loader最先执行
            }
        ]
}

四、Plugins
字面意思就是插件。通常一些loader没办法完成的事情都可以通过插件来完成,他主要用于对构建产物的优化,资源管理以及环境变量的注入。
注:在整个构建环节都可以去使用plugins,他作用于整个构建过程,webpack会在构建过程中不停的去广播一些事件,而plugins可以监听这些事件 从而进行相对应的处理
一些常见的plugins


image.png

五、mode
webpack构建模式,有三个可选值
development,production,none
设置不同的模式webpack会为你默认启动一些优化选项


image.png

了解完了以上几个webpack的关键点之后 让我们来做个小小的练习吧。
打包构建一个vue应用。
基本配置

首先分析一下想要打包vue文件肯定是需要能够解析vue的loader的,这里vue官方就给我们提供了这样一个loader vue-loader,下面是官方文档
https://vue-loader.vuejs.org/zh/guide/#vue-cli
根据官网的教程,可以得到以下的基本配置

const path = require('path');//nodejs的核心模块,专门用来处理路径问题
const {VueLoaderPlugin} = require("vue-loader");

module.exports = {
    //入口
    entry: "./src/main.js",//相对路劲
    //输出
    output: {
        //所有文件的输出路径
        //__dirname: nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"),//绝对路径
        //最终产物的文件名,可以指定 也可以使用[name]占位 这样的话就会使用入口文件的名字,多入口的时候必须以占位的形式
        filename: "bundle.js",
        //代码块的文件名
        // chunkFilename:"[name].chunk.js",
        clean:true //自动删除上次打包的结果
    },
    //加载器
    module: {
        rules: [
            //loader的配置
            {//通过babel-loader解析es6es7语法转为es5
                test:/\.js$/,
                use:[
                    "babel-loader"
                ]
            },
            {
              //通过vue-loader解析vue文件
              test:/\.vue$/,
                use:[
                    "vue-loader"
                ]
            },
        ]
    },
    //插件
    plugins: [
        //plugin的配置
        new VueLoaderPlugin()
    ],
    //模式
    mode: "development",
    // devtool: "source-map"//输出源代码
}

要注意可不是只用上一个vue-loader就行了哦,还需要配合VueLoaderPlugin插件才能完成对vue文件的打包。
接下来我们准备一个入口文件以及一个vue文件作为跟组件。

//main.js
import Home from './vue/Home.vue'
import {createApp} from 'vue'
console.log(createApp,Home,123)
const app = createApp(Home).mount('#app')
console.log(app)


//Home.vue
<template>
<div>{{msg}}</div>
</template>

<script>
import {ref} from "vue";

export default {
  name: "Home",
  setup(){
    const msg = ref('Home test')
    return{
      msg
    }
  }
}
</script>

<style scoped>

</style>
最后在准备一个html文件引入我们打包后的js文件即可
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>hello webpack</div>
<div id="app"></div>
<script src="../dist/bundle.js"></script>
</body>
</html>
注意引入的js的文件要么异步加载要么放在跟标签后面,不然就会出现vue找不到跟标签挂在元素了
image.png

这样就完成了一个简单的编译打包vue文件的过程。

下面看看webpack是如何解析css和字体图片文件的

首先 解析css 需要用到两个loader,一个是css-loader用来将css资源编译成common.js的模块到js中,第二个 style-loader将js中的css通过创建style标签的形式添加到html中,以生效

            {
                test: /\.css$/, //只检测.css文件
                use: [ //执行顺序:从右到左或者从下到上,最末尾的loader最先执行
                    "style-loader",//将js中的css通过创建style标签的形式添加到html中,以生效
                    "css-loader", //将css资源编译成common.js的模块到js中
                ]
            },

这样就可以完成对css的解析。


image.png

打包图片资源和字体资源
使用到file-loader或者url-loader

            //打包图片资源
            {
                test: /\.(png|jpe?g|gif|webp|svg)$/,
                use:[
                    {
                        loader: "url-loader",
                        options: {
                            limit:10*1024
                        }
                    }
                ]
            },

这里使用了url-loader,因为url-loader可以配置将小于多少大小的文件打包成base64,其内部也是使用的file-loader,只不过功能做了一些扩展。
PS:base64格式有利于减少http请求,但是如果文件过大 生成的base64也会特别大。所以只适合让小文件转成base64格式

接下来去学习webpack中的文件监听。
webpack提供了一个watch属性当他为true的时候 文件改变就会自动触发webpack的重新构建,这和我们日常开发中的热更新不同,他只是重新生成了构建产物 但是并不会触发浏览器的刷新,所以还需要我们手动刷新浏览器。
也可以在webpack运行命令后面加上--watch开启监听模式

"watch-build": "npx webpack --watch"
这样执行这个命令就可以开启监听模式

原理分析


image.png

讲到了文件监听那就不得不提webpack的热更新了。热更新需要用到两个包
webpack-dev-server和hot-module-replacement-plugin
以下简称WDS和HMR
热更新的原理就是通过WDS启动一个本地服务器,此时构建出的东西就不会输出实际的文件了 而是会被放到本地的服务器上。然后HMR会在bundle里注入一个HMR runtime,这个东西是存在于浏览器端的,他会和WDS建立一个scoket连接。当有文件被修改的时候会再次经过webpack编译,webpack编译后就会将最新的代码发送至本地服务器上,本地服务器就会通知runtime runtime再去修改局部的变更。(PS:所以我们在开发项目式 run dev是看不到dist文件夹的,如果想查看run dev生成了什么东西可以在本地服务端口后面拼上webpack-dev-server即可)。


image.png

文件指纹

在webpack中所谓的文件指纹其实就是指打包生成的文件名后的hash值。那这个哈希值有什么用呢。在每次构建项目的时候可能只是改动了一两个文件,如果文件名不发生变化,那在浏览器上是会被缓存下来的,所以用户没办法第一时间看到更新之后的资源。而如果我们给发生了变化的文件加上新的哈希值,浏览器就会去下载最新的。而那些没发生变化的则继续沿用缓存里的。这样可以极大的利用浏览器缓存。


image.png

webpack里得哈希大概分为以上两种,一般我们打包静态文件会选择Hash 而js则会选择Chunkhash,css则是Contenthash。
用法也很简单,直接在输出得文件名里使用占位符即可。

 output: {
        //所有文件的输出路径
        //__dirname: nodejs的变量,代表当前文件的文件夹目录
        path: path.resolve(__dirname, "dist"),//绝对路径
        //最终产物的文件名,可以指定 也可以使用[name]占位 这样的话就会使用入口文件的名字,多入口的时候必须以占位的形式
        filename: "[name]_[chunkhash:8].js", 这里我们只取前八位就行,默认是32位
        //代码块的文件名
        // chunkFilename:"[name].chunk.js",
        clean:true //自动删除上次打包的结果
    },

之前我们得css都是通过style-loader以style标签得形式插入html,要使用哈希得话我们就得借助另一个loader,让css以link标签得方式引入。

npm install --save-dev mini-css-extract-plugin

插件文档:https://webpack.docschina.org/plugins/mini-css-extract-plugin/
具体使用方法看文档即可

  //使用此插件将css分离出文件通过link引入
        new MiniCssExtractPlugin({
            filename:'[name]_[contenthash:8].css'
        })

代码压缩

webpack是自带了js代码压缩的,所以下面主要介绍一下css的压缩和html的压缩
css的压缩主要用到的插件有optimize-css-assets-webpack-plugin以及CssMinimizerPlugin
两者都是依赖于cssnano的,所以要先安装一下cssnano。
使用方法也很简单,在plugins里new一下就行。
html的压缩需要借助HtmlWebpackPlugin,配置一下minify对象即可

new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'public/index.html',
            inject: true,//配置所有js资源放置在html得哪个位置
            minify:{
                //压缩配置
                collapseWhitespace: true,
                preserveLineBreaks:false,
                html5:true,
                minifyCSS:true,
                minifyJS:true,
                removeComments: true,
            }
        }),

以上就是webpack的基础入门了

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容