当前位置: 首页 > news >正文

前端工程化(Gulp、Webpack)-webpack

什么是Webpack

现代 JavaScript 应用程序的静态模块打包器(module bundler),它能够根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源;本身只支持javascript,通过loader可以支持其他资源,每个资源即一个模块,在webpack中一切皆模块;通过plugins的扩展,拥有强大的功能。已经成为目前最流行,社区最活跃的打包工具。

官网:https://doc.webpack-china.org
image

为什要使用Webpack

近年来 Web 应用变得更加复杂与庞大,Web 前端技术的应用范围也更加广泛,为了方便维护和管理,需要用模块化的思想来组织代码,产生了一些需求:

  • 将依赖树拆分成按需加载的块
  • 初始化加载的耗时尽量少
  • 各种静态资源都可以视作模块
  • 将第三方库整合成模块的能力
  • 可以自定义打包逻辑的能力
  • 适合大项目,无论是单页还是多页的 Web 应用

模块化

传统方式<script>

缺点很明显:

  • 全局作用域下容易造成变量冲突,如jq和zepto
  • 文件只能按照 <script> 的书写顺序进行加载
  • 开发人员必须主观解决模块和代码库的依赖关系
  • 在大型项目中各种资源难以管理,长期积累的问题导致代码库混乱不堪
AMD

与 CommonJS 最大的不同在于它采用异步的方式去加载依赖的模块。 AMD 规范主要是为了解决针对浏览器环境的模块化问题,最具代表性的实现是 requirejs。

缺点在于JavaScript 运行环境没有原生支持 AMD,需要先导入实现了 AMD 的库后才能正常使用。

CMD

规范和 AMD 很相似,推崇就近依赖,只有在用到某个模块的时候再去require,国产,代表SeaJS

缺点依赖 SPM 打包,模块的加载逻辑偏重

CommonJS

一种使用广泛的 JavaScript 模块化规范,核心思想是通过 require 方法来同步地加载依赖的其他模块,通过 module.exports 导出需要暴露的接口。 CommonJS 规范的流行得益于 Node.js 采用了这种方式,后来这种方式被引入到了网页开发中。

缺点在于这样的代码无法直接运行在浏览器环境下,必须通过工具转换成标准的 ES5。

ES6 模块化

国际标准化组织 ECMA 提出的 JavaScript 模块化规范,它在语言的层面上实现了模块化。浏览器厂商和 Node.js 都宣布要原生支持该规范。它将逐渐取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。

缺点在于目前无法直接运行在大部分 JavaScript 运行环境下,必须通过工具转换成标准的 ES5 后才能正常运行。

一、安装

全局安装:

npm install webpack -g

项目依赖安装:

npm install webpack --save-d

在命令行使用

webpack <entry> [<entry>] <output>
  • entry:入口文件,可以是多个
  • output:输出文件的路径及名字

更多命令行用法:https://doc.webpack-china.org...

指定配置文件

默认为根目录的webpack.config.js,也可以手动指定

webpack [--config webpack.config.js]  //在命令行中手动指定配置文件

完整的配置文件模板:https://doc.webpack-china.org...

核心配置

Context

string

基础目录(上下文),绝对路径,用于从配置中解析入口起点(entry point)和 loader,
默认为执行启动 Webpack 时所在的当前工作目录。可以通过以下方式改变:

module.exports = {
  context: path.resolve(__dirname, 'app')
}

Entry

string | [string] | object { <key>: string | [string] } | (function: () => string | [string] | object { <key>: string | [string] })

应用程序的起点入口,webpack将从这里开始查找依赖关系

  • 字符串或数组:只会生成一个 Chunk,会被命名为 main
  • 对象:每个键(key)生成一个chunk,名称为对应的key,入口则为对应的value
  • 函数:动态生成入口地址
entry: {
  home: "./home.js",
  about: "./about.js",
  contact: "./contact.js"
}

Output

object
最终输出的文件及路径

  • Output.filename: 输出文件名,可以使用占位符
id            Chunk的唯一标识,从0开始
name        Chunk的名称
hash        Chunk的唯一标识的 Hash 值
chunkhash    Chunk内容的 Hash 值
query       Chunk的query,文件名?后面的字符串
  • Output.path: 存放的本地目录,必须是 string 类型的绝对路径
output:{
    path: path.resolve(__dirname, 'dist_[hash]')
}
  • Output.publicPath: 远程资源的URL前缀,默认为空
output:{
    path: path.resolve(__dirname, "public/assets"),
    publicPath: "https://cdn.example.com/assets/"
}

Module

配置如何处理模块。

module.noParse

RegExp | [RegExp] | function

防止 webpack 解析那些与给定正则表达式相匹配的文件

noParse: function(content) {
  return /jquery|lodash/.test(content);
}
module.rules

array

为模块匹配对应的loader,并进行相关设置。值为数组,下位用Rule表示每一个项

  • Rule.test:匹配需要解析的文件
  • Rule.include:定位包含的文件夹,优先于test
  • Rule.exclude:排除的文件及文件夹,优先于test、include
  • Rule.loader:配置解析的loader,可以是String或者Array。
  • Rule.options:loader配置参数
  • Rule.use:配置解析的loader,一般用于使用多个loader,数组,每一项即为一个loader,和Rule.loader、Rule.options用法一样

常用loader:https://doc.webpack-china.org...

// css
{
    test: /\.css$/,
    use: [
        {
            loader: "style-loader"
        }, {
            loader: "css-loader",
            options: {
                modules: true, // 指定启用css modules
                localIdentName: '[name]__[local]--[hash:base64:5]' // 指定css的类名格式
            }
        }
    ]
}
//图片
{
    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
    loader: 'url-loader',
    options: {
      limit: 10000,
      name: utils.assetsPath('img/[name].[hash:7].[ext]')
    }
}

Resolve

object

配置模块如何解析。 Webpack 内置 JavaScript 模块化语法解析功能,默认会采用模块化标准里约定好的规则去寻找,但你也可以根据自己的需要修改默认的规则。

resolve.alias

object

创建 import 或 require 的别名,来确保模块引入变得更简单。

alias: {
  Utilities: path.resolve(__dirname, 'src/utilities/'),
  Templates: path.resolve(__dirname, 'src/templates/')
}
resolve.extensions

array

自动解析的文件的扩展名,这些文件在引入时可不带扩展名

//file.json
extensions: [".js", ".json"]
import File from '../path/to/file'
resolve.mainFields

array

当从 npm 包中导入模块时,此选项将决定在 package.json 中使用哪个字段导入模块。一些第三方模块会针对不同环境提供几分代码,Webpack 会根据 mainFields 的配置去决定优先采用那份代码。

resolve.modules

array

告诉 webpack 配置 Webpack 去哪些目录下寻找第三方模块,默认为node_modules、

Plugins

array

插件配置,接受一个数组,数组里每一项都是一个要使用的 Plugin 的实例,Plugin 需要的参数通过构造函数传入。

在 Webpack 中接入 Plugin并不复杂,复杂在于每个插件自身提供的配置项。

var webpack = require('webpack');
// 导入非 webpack 默认自带插件
var ExtractTextPlugin = require('extract-text-webpack-plugin');

// 在配置中添加插件
plugins: [
  new ExtractTextPlugin({
    filename: 'build.min.css',
    allChunks: true,
  })
]

常用插件:https://doc.webpack-china.org...

DevServer

启动一个本地服务器,并支持实时预览,热替换,Source Map

devServer: {
  contentBase: path.join(__dirname, "dist"),
  compress: true,
  port: 9000
}
devServer.hot

默认:false;是否启用模块热替换功能(局部更新),关闭则为整个页面刷新。

devServer.inline

默认:true;是否启用内联模式(inline mode)

  • 如果开启 inline,DevServer 会在构建完变化后的代码时通过代理客户端控制网页刷新。
  • 如果关闭 inline,DevServer 将无法直接控制要开发的网页。这时它会通过 iframe 的方式去运行要开发的网页,当构建完变化后的代码时通过刷新 iframe 来实现实时预览。
devServer.historyApiFallback

boolean|object

使用了 HTML5 History API 的单页应用。 要求服务器在针对任何命中的路由时都返回一个对应的 HTML 文件。

devServer.contentBase

boolean|string|array
配置 DevServer HTTP 服务器的文件根目录。 默认情况下为当前执行目录,通常是项目根目录。

devServer.host

string

配置 DevServer 服务监听的地址。

devServer.number

number

配置 DevServer 服务监听的端口号。

devServer.compress

boolean

是否启用gzip压缩,默认false

devServer.open

boolean

首次构建完成是否打开浏览器

Devtool

string|false

配置webpack如何生成Source Map。

Target

string | function(compiler)

制定构建环境。默认web

Watch 和 WatchOptions

监听模式及配置

module.export = {
  // 只有在开启监听模式时,watchOptions 才有意义
  // 默认为 false,也就是不开启
  watch: true,
  // 监听模式运行时的参数
  // 在开启监听模式时,才有意义
  watchOptions: {
    // 不监听的文件或文件夹,支持正则匹配
    // 默认为空
    ignored: /node_modules/,
    // 监听到变化发生后会等300ms再去执行动作,防止文件更新太快导致重新编译频率太高
    // 默认为 300ms  
    aggregateTimeout: 300,
    // 判断文件是否发生变化是通过不停的去询问系统指定文件有没有变化实现的
    // 默认每秒问 1000 次
    poll: 1000
  }
}

技巧

  • 常用操作配置到npm script
  • 想让源文件加入到构建流程中去被 Webpack 控制,配置 entry。
  • 想自定义输出文件的位置和名称,配置 output。
  • 想自定义寻找依赖模块时的策略,配置 resolve。
  • 想自定义解析和转换文件的策略,配置 module,通常是配置 module.rules 里的 Loader。
  • 其它的大部分需求可能要通过 Plugin 去实现,配置 plugin。

vue-cli简介

结构及文件简介:http://blog.csdn.net/hongchh/...

由vue官方提供的一套快速生成项目模板的脚手架,内置了几套模板,可以根据自己需要进行拉取。目的是为了让开发者能够快速进行项目开发,而不用把时间花费在项目构建上。

├── README.md                       // 项目说明文档
├── node_modules                    // 项目依赖包文件夹
├── build                           // 编译配置文件,一般不用管
│   ├── build.js
│   ├── check-versions.js
│   ├── dev-client.js
│   ├── dev-server.js
│   ├── utils.js
│   ├── vue-loader.conf.js
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   └── webpack.prod.conf.js
├── config                          // 项目基本设置文件夹
│   ├── dev.env.js              // 开发配置文件
│   ├── index.js                    // 配置主文件
│   └── prod.env.js             // 编译配置文件
├── index.html                      // 项目入口文件
├── package-lock.json           // npm5 新增文件,优化性能
├── package.json                    // 项目依赖包配置文件
├── src                             // 我们的项目的源码编写文件
│   ├── App.vue                 // APP入口文件
│   ├── assets                      // 初始项目资源目录,会被webpack处理
│   │   └── logo.png
│   ├── components              // 组件目录
│   │   └── Hello.vue           // 测试组件,回头删除
│   ├── main.js                 // 主配置文件
│   └── router                      // 路由配置文件夹
│       └── index.js            // 路由配置文件
└── static                          // 资源放置目录,不会被webpack处理

相关文章:

  • Squirrel GUI+ Phoenix 连接Hbase
  • 集群介绍,keepalived介绍,用keepalived配置高可用集群
  • 011-Spring Boot 运行流程分析SpringApplication.run
  • Linux Centos 7 - 系统安装
  • 宝哥iOS网络篇-AFNetworking基础使用指南
  • JS数组方法汇总
  • [解决方案]sql server复制需要有实际的服务器名称才能连接到服务器
  • 远程管理防火墙一
  • 用yarn替代npm
  • spring boot 整合apache shiro
  • linux用户操作
  • python 遍历本地文件
  • ShaderForge插件分享
  • eclipse不能正常启动
  • ReSharper2017.3的列对齐、排版格式、列对齐错误的修复
  • 「面试题」如何实现一个圣杯布局?
  • 【笔记】你不知道的JS读书笔记——Promise
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • canvas 高仿 Apple Watch 表盘
  • const let
  • CSS3 变换
  • go语言学习初探(一)
  • HTTP那些事
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • passportjs 源码分析
  • PHP变量
  • Python_网络编程
  • Python连接Oracle
  • Vue.js-Day01
  • Vue全家桶实现一个Web App
  • 使用阿里云发布分布式网站,开发时候应该注意什么?
  • 算法-插入排序
  • 微信如何实现自动跳转到用其他浏览器打开指定页面下载APP
  • 我与Jetbrains的这些年
  • 正则表达式小结
  • 06-01 点餐小程序前台界面搭建
  • C# - 为值类型重定义相等性
  • 选择阿里云数据库HBase版十大理由
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • ​如何使用ArcGIS Pro制作渐变河流效果
  • # 飞书APP集成平台-数字化落地
  • #Spring-boot高级
  • (5)STL算法之复制
  • (非本人原创)史记·柴静列传(r4笔记第65天)
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (一)基于IDEA的JAVA基础1
  • ******之网络***——物理***
  • .Net IOC框架入门之一 Unity
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .NET6 命令行启动及发布单个Exe文件
  • .net快速开发框架源码分享
  • @require_PUTNameError: name ‘require_PUT‘ is not defined 解决方法
  • [1] 平面(Plane)图形的生成算法