webpack从入门到深入

初识webpack:配置文件名称

webpack 默认配置文件:webpack.config.js
可通过 webpack --config 指定配置文件

webpack基本配置如下图:

image.png

webpack 4.0出来以后称有一个零配置的webpack(也就是我们不需要编写webpack配置,他就会使用默认进行打包)

image.png

如上图零配置的webpack 是包含entryoutput 的,对 mode、module、plugins 没有做设定。

环境的搭建,安装webpack。

1.安装webpack 之前需要安装node.js 和 npm 包管理器。
2.node.js 的安装地址 https://nodejs.org (mac可使用nvm来进行指定版本的安装)
3.安装完毕可使用命令 node -vnpm -v 来检查是否安装成功。
4.安装完毕node.js 和npm 之后就可以安装webpack了。webpack 4 里面是将(webpack内核和webpack-cli 进行了一个分离),所以我们在实际项目的时候同时要安装 webpackwebpack-cli . 下面代码演示一下。

$ mkdir my_project  //创建一个文件夹
$ cd my_project    // 进入
$ npm init -y       // 初始化一个package.json文件,-y是一切选项默认
$ npm install webpack webpack-cli --save-dev   //--save-dev (将依赖添加到devdependencies里面而不是dependencies)
$ ./node_modules/.bin/webpack -v  //来检查版本

一个简单的webpack来了解它的使用

/*
 * webpack.config.js的基础配置
 * 基于以下entry我们需要建一个src的文件夹,并在下面建index.js文件
 * 如何运行打包命令: ./node_modules/.bin/webpack 
 */
"use strict"

const path = require('path');          //node.js当中的一个内置模块

module.exports = {
  entry: './src/index.js',            //需要打包的入口文件
  output: {
    path: path.join(__dirname, '/dist'),     //配置路径 __dirname当前文件夹路径
    filename: 'bundle.js'            //配置output输出来的文件名
  },
  mode: 'production'
}

指定webpack的运行命令

你是不是会觉得运行打包webpack的命令很长,我们马上来配置一下
在package.json中script 加 "build" : "webpack"

image.png

webpack核心概念
  • entry

Entry用来指定 webpack 的打包入口
为什么用entry作为打包入口,对于webpack的构建机制有很大关系,在webpack眼中所有的资源都是模块,js、html或者是图片文字等。他们都互相依赖形成一个tree。而entry就是作为整个依赖的入口。
定义entry有两种形式:
1.单入口:entry是一个字符串

module.exports={
       entry :'./src/index.js'
};

2.多入口:entry是一个对象 (值为key : value)

module.exports={
       entry :{
        app : './src/app.js',
        adminApp:'./src/adminApp.js'
   }
};
  • output

output用来告诉 webpack 如何将编译后的文件输出到磁盘

/*
 * output 用法:单入口配置
 * 单入口的filename 可以写死。
 */

module.exports={
       entry :'./path/to/me/my/entry/file.js',
       output : {
         filename : 'bundle.js',
         path :  __dirname + '/dist'
   }
};

/*
 * output 用法:多入口配置
 * 在output 中针对多入口并没有提供与entry一样的键值对的形式而是通过占位符的形式。'[name].js'
 */

module.exports={
        entry :{
               app : './src/app.js',
               adminApp:'./src/adminApp.js'
   },
       output : {
         filename : '[name].js',
         path :  __dirname + '/dist'
   }
};
  • loaders

wbepack 开箱即用只支持JS 和JSON 两种文件类型,通过 Loaders 去支持其他文件类型并且把它们转化成有效的模块,并且可以添加到依赖图中。
本身是一个函数接受源文件作为参数,返回转化的结果
常见的Loaders

image.png

Loaders的用法

module.exports={
       entry :'./path/to/me/my/entry/file.js',
       output : {
         filename : 'bundle.js',
         path :  __dirname + '/dist'
    },
module : {
     rules :[
             {test : /\.txt$/,use : 'raw-loader'}            //  test 指定匹配规则
      ]                                                                   //  use 指定使用的 loader 名称
   }
};
  • plugins

前面的loaders 是用来处理 webpack 不能解析的文件,plugins 是用来增强 webpack的。
plugins 插件用于打包完文件的优化,资源管理和环境变量的注入 (你可以理解为loaders完成不了的都由plugins完成)
作用于整个构建过程
常见的plugins有哪些

image.png

/*
 * plugins 的用法 
 */

module.exports={
       entry :'./path/to/me/my/entry/file.js',
       output : {
         filename : 'bundle.js',
         path :  __dirname + '/dist'
    },
       plugins : [
        new HtmlWebpackPlugin({template : './src/index.html'})      // 对于多个插件我们都放到plugins 数组里面
  ]
};
  • mode

mode 用来指定当前打包的环境 :production、development 还是none (在webpack 4 以前是没有mode这个概念的)
设置mode可以使用 webpack 内置的函数,默认值为production。(如果没有设置webpack什么都不会做)
mode 的内置函数功能


image.png

webpack是如何来解析ES6和 React JSX

原生的webpack是支持js的但是对于ES6的特殊语法 webpack 并不是很了解。

image.png

首先 如上我们需要在rules 里面进行配置(test:匹配文件,use:指定使用的loader),babel-loader是依赖于babel(因此我们需要在项目中使用babel的配置文件 .babelrc 中增加es6的babel preset 配置)
image.png

介绍一下 babel 主要有两个比较重要的概念

  1. preset (是一系列babel plugins的集合)
  2. plugins (你可以理解为一个plugin对应一个功能)
    这里我们要解析ES6 我们只需要安装"@babel/preset-env"
/*
 * 用命令
 */

npm i @babel/core  @babel/preset-env  babel-loader  -D   //-D是 --save-dev的简称
npm  @babel/preset-react  //用来解析jsx

webpack 解析css

module.exports = {
    entry: {
        index: './src/index.js',
        search: './src/search.js'
    },
    output: {
        path: path.join(__dirname, '/dist'),
        filename: '[name].js'
    },
    mode: 'production',
    module: {
        rules: [{ test: /\.js$/, use: 'babel-loader' },
        { test: /\.css$/, use: ['style-loader', 'css-loader'] }  //css 是链式调用,执行顺序是从右到左所以要先写style-loader
        ]
    }
}

css-loader 用于加载 .css 文件,并且转化成 commonjs对象
style-loader 将样式通过<style> 标签插入到head中

解析Less和Sass

less-loader 用于将less转换成css

/*
 * npm i less less-loader -D       //因为less-loader 是依赖于less的
 */

module: {
        rules: [{ test: /\.js$/, use: 'babel-loader' },
        { test: /\.css$/, use: ['style-loader', 'css-loader'] },
        { test: /.less/, use: ['style-loader', 'css-loader', 'less-loader'] }
        ]
    }

如何解析图片和字体

解析图片和字体都可使用 file-loader 来进行处理

module: {
        rules: [{ test: /\.js$/, use: 'babel-loader' },
        { test: /\.css$/, use: ['style-loader', 'css-loader'] },
        { test: /.less/, use: ['style-loader', 'css-loader', 'less-loader'] },
        { test: /.(png|svg|jpg|jpeg|svg)/, use: 'file-loader' },
        { test: /.(woff|woff2|eot|ttf|otf)/, use: 'file-loader' }
        ]
    }

除此之外还可以使用 url-loader 他会对于小于限定大小的资源(小图片或小字体进行base64的转换),它内部也是用了file-loader的。

module: {
        rules: [{ test: /\.js$/, use: 'babel-loader' },
        { test: /\.css$/, use: ['style-loader', 'css-loader'] },
        { test: /.less/, use: ['style-loader', 'css-loader', 'less-loader'] },
        { test: /.(png|svg|jpg|jpeg|svg)/, use: 'file-loader' },
        { test: /.(woff|woff2|eot|ttf|otf)/, use:[loader :  'url-loader' ,options : {limit : 10240}]}
        ]
    }

/*
 * url-loader 他会接受一个参数通过options来传进去。
 * limit 单位是字节。10240代表10k 小于10k他会进行base64的转换 
 */

webpack中的文件监听

文件监听是在发现源代码发生变化时,自动重新构建出新的输出文件。
webpack 开启监听模式,有两种方式:

  • 启动 webpack 命令时,带上 --watch 参数 (唯一缺陷:每次需要手动刷新浏览器)
  • 在配置 webpack.config.js 中设置 watch : true
    文件监听的原理和分析


    image.png

    简单介绍文件监听,webpack 会轮询判断文件的最后编辑时间是否发生变化,一开始我们会有一次文件修改时间,他会把这个时间存储起来,下一次再有修改他会和上一次做对比如果发生变化它不会立刻告诉监听者,而是先缓存起来。监听等待。轮询的时间由poll控制。

webpack中热更新及原理分析

webpack-dev-server 对比 --watch 的优点 经常与HotModuleReplacementPlugin 一起使用

image.png

还有一种方式 webpack-dev-middleware 这种需要自己配置比较灵活。(可移步官网查看)
热更新的与原理分析
image.png

热更新分两个阶段一个是起步还有就是热更新
起步阶段是1/2、A、B,更新是1,2,3,4,5

文件指纹策略 (文件指纹不能和热更新一起使用)

什么是文件指纹? (打包后输出的文件名的后缀)
用处?(版本的管理、合理的运用缓存)
如何生成


image.png

contenthash
根据文件内容来定义hash,内容不变则contenthash不变,通常用于css打包,避免受同一个chunk的js文件修改的影响。配合MiniCssExtractPlugin使用,MiniCssExtractPlugin和style-loader是互斥的


image.png

图片的文件指纹
image.png

代码压缩主要有三个部分 (HTML、CSS、JS)

  • js文件的压缩 (webpack内置了 uglifyjs-webpack-plugin

我们打包好的js默认都是压缩的,所以我们不需要再做什么了(当然你也可以下载这个插件为这个下载一些其他的参数)

  • css的压缩

需要配合 cssnano 来使用。

image.png
  • html的压缩


    image.png

自动清理构建目录产物

image.png

const CleanWebpackPlugin = require('clean-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
的问题。 v3升级完只剩一种方式解构了
主要是clean-webpack-plugin这个插件进行了大版本升级

PostCSS插件autoprefixer自动补全CSS3前缀

使用 npm i postcss-loader autoprefixer -D
以下是 autoprefixer 更新后的新的书写格式 (官方推荐写在package.json中)

 官方推荐写法
{
  "private": true,
  "dependencies": {
    "autoprefixer": "^6.5.4"
  },
  "browserslist": [
    "last 1 version",
    "> 1%",
    "IE 10"
  ]
}
························
// 通过配置  .browserslistrc 来使用
{ loader: 'postcss-loader', 
   options: { plugins: () => [require('autoprefixer')]     //他会自动去寻找 .browserslistrc 这个
      }
 }
//  如果想直接设置也可以改成   overrideBrowserslist   (这样终端不会报错)
{ loader: 'postcss-loader', 
   options: { plugins: () => [require('autoprefixer')({ overrideBrowserslist: ['ios 7' , ' last 2 version ']})]     
      }
 }

移动端css px自动转成rem

CSS 媒体查询实现响应式布局


image.png

css3 提出了rem 的单位 (rem是什么?) ,webpack中也有相应的loader
W3C 对rem 的定义:font-size of the root element
rem 和 px 的对比:(.rem是相对单位 , .px是绝对单位)


image.png

静态资源内联

image.png

raw使用的时候要注意使用0.51的这个版本(新版本有些问题)


image.png
image.png

1.安装

 npm i raw-loader@0.5.1 -D      // 下载指定版本

2.引入

//  html 引入
${require('raw-loader!./meta.html')}

// js引入  (还需要babel-loader来进行解析es6)
${require('raw-loader!babel-loader!./meta.html')}

多页面应用打包通用方案

  • 多页面应用(MPA)概念

每一次页面跳转的时候,后台服务器都会给返回一个新的 html 文档,这种类型的网站也就是多页网站,也叫做多页应用

利用glob.sync以同步的方式查询出来


image.png

1.安装

npm i glob -D

·····················
// 动态配置entry 和htmlwebpackplugin
const glob = require('glob');

const setMPA = () => {
    const entry = {};
    const htmlWebpackPlugins = [];

    const entryFiles = glob.sync(path.join(__dirname, './src/*/index.js'));

    Object.keys(entryFiles)
        .map((index) => {
            const entryFile = entryFiles[index];

            const match = entryFile.match(/src\/(.*)\/index\.js/);
            const pageName = match && match[1];
            entry[pageName] = entryFile;
            htmlWebpackPlugins.push(
                new HtmlWebpackPlugin({
                    template: path.join(__dirname, `src/${pageName}/index.html`),
                    filename: `${pageName}.html`,
                    chunks: [pageName],
                    inject: true,
                    minify: {
                        html5: true,
                        collapseWhitespace: true,
                        preserveLineBreaks: false,
                        minifyCSS: true,
                        minifyJS: true,
                        removeComments: false

                    }
                })
            )
        })
    return {
        entry,
        htmlWebpackPlugins
    }
}

const { entry, htmlWebpackPlugins } = setMPA();

/////////////////持续更新中

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

推荐阅读更多精彩内容