Webpack 的简单介绍

7 篇文章 0 订阅
5 篇文章 0 订阅

本文介绍了一些 webpack 的核心概念以及一些概念术语,并对核心配置做了一些简单的用法讲解。建议刚刚接触 Webpack 的朋友可以先了解一下。想了解更多 Webpack 使用以及配置的话可以参考我的下一篇文章: 从零开始搭建一个 Webpack 开发环境配置(附 Demo)


为什么需要使用 webpack

  • 模块化开发的趋势
    我们在开发的过程中,之前都是使用引入 script 的方式进行各种工具和插件的引入,但是这样会造成很大程度上的全局污染,所以引入了 模块化 的概念,但是不管是 commomJs 还是 CMD,AMD 的方式,浏览器都无法识别,而使用 webpack 就可以自动的将文件编译成浏览器可以识别的代码

  • less、sass 以及 ES6 语法的使用
    同样的,直接使用 less、sass 和 ES6 语法,直接使用,浏览器甚至 node 环境也无法正常识别,所以这时候 loader 就派上用场了,可以使用 less-loader、sass-loader 以及 babel-lodaer 对对应的文件进行转换之后,就可以正常的编译了

  • 监听文件的变化并自动刷新网页,做到实时预览

  • 提供 HTTP 服务而不是使用本地文件预览

  • 对于打包后的文件进行压缩,模块拆分,减小打包后的文件体积

  • 等等还有很多别的优势,这里我就不一一列举了


webpack 安装

  • 全局安装:

    npm install --global webpack
    
  • 本地安装:

    npm install --save-dev webpack
    npm install --save-dev webpack-cli
    

Webpack 概念

webpack 是一个可高度配置的现代 JavaScript 应用程序模块打包器。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

Webpack 核心概念

入口

入口点可以告诉 webpack 从哪里启动以及遵循依赖关系图,以此知道要打包什么东西。你可以考虑将待打包文件的根目录作为你应用程序的入口点。

个人理解:入口就是 webpack 在处理应用程序时,需要知道从哪个文件开始执行,这个文件就是整个程序的入口文件。

用法:entry: string|Array|Object

基本用法

webpack.config.js

const config = {
  entry: './src/index.js'
};

module.exports = config;
数组语法

一般适用于多页面应用,多个入口的场景。

webpack.config.js

const config = {
  entry: ['./src/entry1', './src/entry2']
};

module.exports = config;
对象语法

一般适用于分离 应用程序(app) 和 第三方库(vendor) 入口。

webpack.config.js

const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
};

module.exports = config;
配置动态入口

假如项目里有多个页面需要为每个页面的入口配置一个 Entry ,但这些页面的数量可能会不断增长,则这时 Entry 的配置会受到到其他因素的影响导致不能写成静态的值。

webpack.config.js

// 同步函数
entry: () => {
  return {
    a:'./pages/a',
    b:'./pages/b',
  }
};
// 异步函数
entry: () => {
  return new Promise((resolve)=>{
    resolve({
       a:'./pages/a',
       b:'./pages/b',
    });
  });
};

输出

上面既然已经有入口文件了,那么 webpack 执行了一系列操作之后,生成的新的打包后的文件应该放到哪儿呢,所以我们需要指定一下。

在 webpack 中配置 output 属性的最低要求是,将它的值设置为一个对象,包括以下两点:

  • filename 用于输出文件的文件名
  • 目标输出目录 path 的绝对路径
基本用法

webpack.config.js

const path = require('path');

const config = {
    entry: './src/index.js',
    output: {
        // 最基本的两个配置要求
        filename: 'bundle.js',  // 输出文件的文件名
        path: path.resolve(__dirname, 'dist')   // 目标输出目录 path 的绝对路径,这里必须是绝对路径
    }
};

module.exports = config;
多个入口起点

如果配置创建了多个单独的 “chunk”,则应该使用占位符(参考*内置的占位符变量*)来确保每个文件具有唯一的名称。

webpack.config.js

const path = require('path');

const config = {
  output: {
    // 最基本的两个配置要求
    filename: '[name]-bundle.js',  // 输出文件的文件名
    path: path.resolve(__dirname, 'dist')   // 目标输出目录 path 的绝对路径
  }
};

module.exports = config;
内置的占位符变量
变量名含义
idChunk 的唯一标识,从0开始
nameChunk 的名称
hashChunk 的唯一标识的 Hash 值
chunkhashChunk 内容的 Hash 值

loader

loader 用于对模块的源代码进行转换。loader 可以使你在 importrequire() 或"加载"模块时预处理文件。
loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

基本使用

例如:加载 css 模块:

  • 安装对应的 loader

    npm install --save-dev style-loader css-loader
    
  • 然后指示 webpack 对每个 .css 使用 css-loader 和 style-loader

webpack.config.js

```js
module.exports = {
    module: {
        rules: [
            { test: /\.css$/, use: ['style-loader', 'css-loader' }
        ]
    }
};
```
配置 loader

rules 配置模块的读取和解析规则,通常用来配置 Loader。其类型是一个数组,数组里每一项都描述了如何去处理部分文件。 配置一项 rules 时大致通过以下方式:

  • 条件匹配:通过 test 、 include 、 exclude 三个配置项来命中 Loader 要应用规则的文件

  • 应用规则:对选中后的文件通过 use 配置项来应用 Loader,可以只应用一个 Loader 或者按照从后往前的顺序应用一组 Loader,同时还可以分别给 Loader 传入参数

  • 重置顺序:一组 Loader 的执行顺序默认是从右到左(从下到上、从后到前)执行,通过 enforce 选项可以让其中一个 Loader 的执行顺序放到最前或者最后

  • 在 Loader 需要传入很多参数时,你还可以通过一个 Object 来描述

  • test include exclude 这三个命中文件的配置项可以传入一个字符串或正则,其实它们还都支持数组类型

具体使用:

module.exports = {
    module: {
        rules: [
            
             {
                // 命中 JavaScript 文件
                test: [
                    /\.js?$/,
                    /\.jsx?$/
                ],
                // 用 babel-loader 转换 JavaScript 文件
                // ?cacheDirectory 表示传给 babel-loader 的参数,用于缓存 babel 编译结果加快重新编译速度
                use: [
                    {
                        loader:'babel-loader',
                        options:{
                            cacheDirectory:true,
                        },
                        // enforce:'post' 的含义是把该 Loader 的执行顺序放到最后
                        // enforce 的值还可以是 pre,代表把 Loader 的执行顺序放到最前面
                        enforce:'post'
                    }
                ],
                // 只命中src目录里的js文件,加快 Webpack 搜索速度
                include: path.resolve(__dirname, 'src')
            },
            {
                // 命中 SCSS 文件
                test: /\.scss$/,
                // 使用一组 Loader 去处理 SCSS 文件。
                // 处理顺序为从后到前,即先交给 sass-loader 处理,再把结果交给 css-loader 最后再给 style-loader。
                use: ['style-loader', 'css-loader', 'sass-loader'],
                // 排除 node_modules 目录下的文件
                exclude: path.resolve(__dirname, 'node_modules')
            }
        ]
    }
};

plugins

Plugin 是用来扩展 Webpack 功能的,通过在构建流程里注入钩子实现,它给 Webpack 带来了很大的灵活性。

基本使用

比如每次打包文件到 dist 文件夹下,就可能导致文件夹下面的文件过多,内容过大,那么此时我们可能需要在打包之前先将 dist 文件下的文件都删除掉,但是每次都手动删除岂不是太麻烦,此时我们就可以使用 clean-webpack-plugin 插件来帮助我们清理 dist 文件夹

插件安装

npm install clean-webpack-plugin --save-dev

webpack.config.js

const CleanWebpackPlugin = require('clean-webpack-plugin');

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

其他概念术语

资源(Asset)

这是一个普遍的术语,用于图片、字体、媒体,还有一些其他类型的文件,常用在网站和其他应用程序。这些文件通常最终在输出(output ) 中成为单个文件,但也可以通过一些东西内联,像 style-loader 或者 url-loader 。

Bundle

由多个不同的模块生成,bundles 包含了早已经过加载和编译的最终源文件版本。

Chunk

这是 webpack 特定的术语被用在内部来管理 building 过程。bundle 由 chunk 组成,其中有几种类型(例如,入口 chunk(entry chunk) 和子 chunk(child chunk))。通常 chunk 会直接对应所输出的 bundle,但是有一些配置并不会产生一对一的关系。

依赖关系图(Dependency Graph)

有时候一个文件依赖于其他文件,webpack 将其视为依赖关系(dependency)。从一个或多个入口点开始,webpack 递归构建一个依赖关系图,里面包含了你的应用程序需要的所有模块/资源(mudule/asset)。

模块(Module)

提供比完整程序接触面(surface area)更小的离散功能块。精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的。

  • 模块解析(Module Resolution):一个模块可以作为另一个模块的依赖模块,resolver 是一个库( library )用于帮助找到模块的绝对路径… 模块将在 resolve.modules 中指定的所有目录内搜索。

Tree Shaking

移除未使用/多余的代码,或者更准确地说,只导入引用的代码。编译器(compiler)(例如 webpack)将通过分析各种 import 语句和引入代码的使用情况,来确定哪些部分的依赖关系被实际使用,删除不是“树”的部分,以实现此功能

第三方库入口点(Vendor Entry Point)

从 app.js 和 vendors.js 开始创建依赖图(dependency graph)。这些依赖图是彼此完全分离、互相独立的,允许你使用 CommonsChunkPlugin 从「应用程序 bundle」中提取 vendor 引用(vendor reference) 到 vendor bundle。可以帮助你在 webpack 中实现被称为长效缓存的通用模式。

优化

  • Bundle 分离(Bundle Splitting)
    这个流程提供一个优化 build 的方法,允许 webpack 为应用程序生成多个 bundle。最终效果是,当其他某些 bundle 的改动时,彼此独立的另一些 bundle 都可以不受到影响,减少需要重新发布的代码量,因此由客户端重新下载并利用浏览器缓存。

  • 代码分离(Code Splitting)
    指将代码分离到每个 bundles/chunks 里面,你可以按需加载,而不是加载一个包含全部的 bundle。


总结

本文简单介绍了一下 Webpack 的作用以及 Webpack 核心概念的用法。想了解更多的朋友可以参考我的下一篇文章:从零开始搭建一个 Webpack 开发环境配置(附 Demo)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值