webpack使用详解

news2025/7/27 21:44:09

什么是webpack

官方定义:从本质上来说,webpack是一个现代的JavaScript的静态模块打包工具。
webpack是前端工程化的一个解决方案。
主要功能: 提供了前端模块化功能支持,模块混淆,代码压缩,处理浏览器JS兼容性,性能优化等强大功能。

webpack前提

学webpack的前提是要知道es6的模块化知识或者commonjs的知识(不用太深),两者都提供模块化功能。es6的模块化是官方标准,较新,将来一定是主流,commonjs比较早就有了,资历深。知道一个或者两个都知道比较好。没学过去看看,不然看不懂webpack例子。
其他前提:
javascript的es5基础 (不用太深)
html (不用太深)
css(不用太深)
node.js(不用太深)

webpack的安装

webpack依赖node.js。没有的需要先安装node.js。就不说怎么安装了。

安装webpack3.6.0这个版本。

npm install webpack@3.6.0 -g

能看到版本号,就表示安装成功了。

webpack -version

webpack的基本使用过程

先把目录创建好,一个main.js文件,这是js的入口文件。dist文件夹是用来放打包后的文件,后面会用到。因为webpack是支持模块化的,所以加了一个mathUtil.js来简单模拟模块化。
在这里插入图片描述
main.js的代码如下:
调用了mathUtils.js的代码,实现简单输出。第一行代码是commonjs的语法,不了解的只需要知道是这是在引用模块就可以了。

const {add,mult}=require("./mathUtils.js")
console.log(add(1,2))
console.log(mult(1,2))

mathUtils.js定义了两个方法并且导出给别人使用。

function add(a, b) {
    return a+b
}

function mult(a, b) {
    return a*b
}

//使用commonJs导出
module.exports = {
    add,
    mult
}

index.html的内容为空,也就是默认的html文本,里面什么都没写。
分析:
现在我们有一个main.js,他引用了mathUtils.js里面的内容。
js有了,那么我们是不是要在js里面引用呢?答案是不要。如果不用webpack,我们可能就会引用多个js文件,比如main.js和mathUtils.js,当然你可能有很多个js文件,都引用也非常的麻烦。webpack可以将这些js文件打包成一个文件。然后你只需要引入打包好的这一个文件就行了,打包也非常的简单。
执行下面的代码,会在dist目录下面生成一个bundle.js文件,这就是打包好的文件,注意这里我们打包的时候只写了main.js,webpack会帮我们把相关联的js文件全部打包进来。这就是webpack帮我们简化步骤的地方,和我们一个个手动引用相比,这里相当于变成了自动引用,我们只需要提供入口js,也就是我们的main.js这一个js文件就可以了。

webpack ./src/main.js ./disk/bundle.js

我们简单看一下生成的这个bundle.js。前面的代码不用看,主要看后面的几行,后面那几行实际上就是把main.js和mathUtils.js的代码合并带一起了,还有一些commonjs的代码,这些代码浏览器还是不识别的,前面生成的一堆看不懂的代码就是给commonjs做支持用的。

/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

const {add,mult}=__webpack_require__(1)
console.log(add(1,2))
console.log(mult(1,2))

/***/ }),
/* 1 */
/***/ (function(module, exports) {

function add(a, b) {
    return a+b
}

function mult(a, b) {
    return a*b
}

//使用commonJs导出
module.exports = {
    add,
    mult
}

/***/ })
/******/ ]);

最后,只需要在index.html里面引用我们生成的bundle.js就可以了。

<script src="./dist/bundle.js"></script>

打开浏览器是可以看到js的执行输出的。
在这里插入图片描述

webpack的配置

前面我们使用webpack打包的时候,是手动指定路径的,这些东西可以写到配置文件里面,方便我们管理。

webpack ./src/main.js ./disk/bundle.js

需要在项目根目录下创建webpack.config.js文件。这是webpack的配置文件,默认就叫这个名字。
在这里插入图片描述
写入下面的内容,然后在终端执行webpack这个命令,不用加任何参数,这时候会报错,告诉你要用绝对路径。实际上,下面path的写法是不对的,需要绝对路径,我们直接写不合适,而是通过node.js提供的path包来获取。

module.exports = {
    entry:"./src/main.js",
    output:{
        path:"./dist",
        filename:"bundle.js"
    }
}

默认情况下是没有path这个包的。我们需要将项目初始化为node工程。
提供下面的命令初始化node工程。要在index.html的父目录执行。

npm init

会叫你填一些值,不要写中文,不是中文的一直默认就可以,后面会说具体配置。
完成之后会多出一个package.json的文件,这是node的配置文件。
里面的内容大致如下。

{
  "name": "meetwebpack",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

在这里插入图片描述
现在就可以使用node提供的path库了。
通过require引入库,通过path.resolve方法获取绝对路径,__dirname是path库提供的项目路径

const path=require("path")
module.exports = {
    entry:"./src/main.js",
    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"bundle.js"
    }
}

现在我们可以直接使用webpack来打包,而不用指定路径了。
在这里插入图片描述

前面的方式运行webpack已经可以用了。但是还有一种更好的方式。那就是使用node的脚步运行webpack。
前面的问题是我们可能存在多个webpack配置文件,一个是生产环境的一个是开发环境的,那么如果环境变了,我们的webpack打包命令需要指定配置文件。
前面没有指定配置文件名称是因为默认配置文件名称就叫做webpack.config.js。

webpack production.config.js

我们可以使用一种更灵活的方式,就是把这些命令配置到脚本里面。下面的命令就是运行build这个脚本,这个脚本是我们自己定义的。

npm run build

在我们的package.json里面有下面的脚本。我们可以在这里面创建我们自己的build脚本,默认写了一个叫test的脚本。

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack"
  }

现在执行npm run build可以实现和原来一样的效果。
在这里插入图片描述
这里还存在一个问题,就是我们在终端执行命令的时候,调用的都是全局的webpack命令。这就会造成问题,因为实际项目中,本地和全局可能因为某些原因需要使用不同的版本。都用全局就会造成问题。
这时候我们需要安装一个本地版本就可以了。

 npm install webpack@3.6.0 --save-dev

执行完后会多出下面的目录。node_modules包含了node的所有模块,有几百个,webpack就在里面。
默认在终端执行webpack都是执行全局的node,除非写成下面的样子

./node_modules/webpack xxxxx

当然现在我们有更好的方式,执行下面的代码就可以了,这就是最终的效果。

npm run build

在这里插入图片描述
并且package.json会多出下面的节点。

  "devDependencies": {
    "webpack": "^3.6.0"
  }

webpack配置CSS

我们先创建css,目录并且添加normal.css文件,内容如下。

body{
    background-color: lightgreen;
}

调整一下js文件结构,把作为入口的main.js暴露再外面。
在这里插入图片描述

这时候我们不要在html中引入css代码了,而是交给webpack来做。

webpack本身并没有支持CSS的功能,这些功能通过loader来提供。
我们只需要加载对应的loader,就可以实现对应的功能。
webpack提供非常多的loader,CSS loader只是其中一个。

我们打开文档:
https://www.webpackjs.com/loaders/#%E6%A0%B7%E5%BC%8F

我们需要用到的css loader就两个,一个是css-loader,用于解析css代码,并返回css代码。如果只单独用这个loader是没有效果的,因为这个loader只负责加载,不负责导出显示到dom中。所以我们还需要一个style-loader模块,这个模块就是专门干这个事的。
在这里插入图片描述
安装模块,webpack 3.6.0对应的0.9.0是可以使用的,太高版本会给警告。
使用npm好像是会直接报错的,但是cnpm只有警告,并且给出提示说当前版本只能对应的版本范围。

npm install --save-dev css-loader@0.9.0
npm install style-loader@0.9.0 --save-dev

然后需要在配置文件里面添加module节点,并添加rules的内容。
需要注意的是,use里面的两个loader是后面的先加载,顺序错了是会报错的,文档里面有这么说。不知道为什么这样设计。

const path=require("path")
module.exports = {
    entry:"./src/main.js",
    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"bundle.js"
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: [
                    { loader: "style-loader" },
                    { loader: "css-loader" }
                ]
            }
        ]
    }
}

这时候执行下面的代码再运行index.html就可以看到css的样式了

npm run build

如果背景色变了就表示成功了。

webpack配置less

less的配置和css的配置是类似的。
这里存在一个困难是版本问题,你根本不知道什么版本和你的webpack匹配。
而且版本号是没有统一的,一个loader是一个独立的版本号。
解决办法就是到github直接搜索你要安装的loader,比如这里的less-loader,随便点击一个tag版本。查看里面的package.json,里面是可以查看到webpack的版本范围的。
对于任意的loader都是类似的,这些loader都是webpack官方发布的。
使用下面的版本对应webpack3.6.0是可以的,只是会告诉你已经废弃,math方法有bug。实际项目还是不要用了,应该升级webpack版本。

npm install --save-dev less-loader@5.0.0 less@2.3.1

在webpack.config.js下面的rules节点下面添加下面的代码。

{
                test: /\.less$/,
                use: [{
                    loader: "style-loader" // creates style nodes from JS strings
                }, {
                    loader: "css-loader" // translates CSS into CommonJS
                }, {
                    loader: "less-loader" // compiles Less to CSS
                }]
            }    

创建css文件夹,在里面准备我们的special.less测试文件。
在这里插入图片描述

@fontSize:50px;
@fontColor:lightblue;
body{
  font-size: @fontSize;
  color: @fontColor;
}

在main.js中引用less

require("./css/special.less")

在index.html中添加如下内容:

<div id="box">
  Hello Webpack
</div>

最后运行。

npm run build

效果正确就表示配置成功了。

webpack对于图片的处理

图片也是需要loader的,在webpack里面图片分为两种情况,在配置文件里面可以配置一个limit属性来判断图片大小是否超过这个指,如果小于这个值,就会被当做base64来处理,如果大于这个值,就当正常的图片文件来处理。
版本一定要写1.1.2,1.0.0是不能显示图片的,对于webpack3.6.9。

npm install --save-dev url-loader@1.1.2

这里的关键点是多了一个limit,也就是我们上面说的图片大小限制。

{
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192
            }
          }
        ]
}

引入两张图片,gun.jpg的大小为4kb,baidu.png的大小为15kb.。在这里插入图片描述

把body的背景指定为gnu.jpg,因为图片大小小于limit,所以图片会以base64的形式传递。

body{
    /*background-color: lightgreen;*/
    background: url("../img/gnu.jpg");
}

在这里插入图片描述
执行下面代码,就可以看到效果了。

npm run build

在这里插入图片描述
如果把图片换成baidu.jpg,就会直接报错。告诉你找不到file-loader。前面讲过,webpack处理图片有两种方式,当图片大小小于limit的时候采用的是base64的字符串方式。这时候就需要用到url-loader,而当图片大于limit的时候,就不能用url-loader,而是要用file-loader.

Module build failed: Error: Cannot find module 'file-loader'

下载file-loader。

 npm install file-loader@2.0.0 --save-dev

配置file-loader。
前面的url-loader是基于file-loader实现的,两者只能写其中一个,同时写是不能生成图片的。
前面的url-loader是基于file-loader实现的,两者只能写其中一个,同时写是不能生成图片的。
前面的url-loader是基于file-loader实现的,两者只能写其中一个,同时写是不能生成图片的。

{
        test: /\.(png|jpg|gif)$/,
        use: [
          {
            loader: 'file-loader',
            options: {}
          }
        ]
      }

编译运行后发现图片不显示。但是dist目录下是生成了图片的。
在这里插入图片描述
我们看下浏览器body的url地址,路径是不对的,应该在前面加一个dist/。这是可以提供配置实现的。

url(d9c8750bed0b3c7d089fa7d55720d6cf.png)

需要子啊webpack配置文件里面添加publicPath这个节点。

    output:{
        path:path.resolve(__dirname,"dist"),
        filename:"bundle.js",
        publicPath:"dist/"
    },

现在baidu.jpg就可以被当做图片显示了。
我们不太可能将所以图片都放在dist根目录下,给dist创建一个img目录是比较合理的,可以提供下面的代码实现。[name]表示原来的文件名[hash:8]表示8位hash值,不写默认32位,[ext]表示扩展名。这样就非常的工程化了。

options: {
       name:"img/[name]-[hash:8].[ext]"
}

输出效果:
在这里插入图片描述

将ES6语法转成ES5语法

webpack的一个最大的优点就是他帮我们做了一些兼容性问题的处理。可以通过babel-loader来实现。

npm install babel-loader@8.0.0 @babel/core @babel/preset-env

在webpack配置文件里面添加下面内容:

{
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/,
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env']
        }
      }
    }

观察输出的js文件,之前的const等这些es6语法就都转化成es5的语法了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/16596.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

腾格尔发新歌《遥远的地方》,成都邓秀菊自发红包朋友圈寻歌词

随着卡特尔世界杯拉开帷幕&#xff0c;著名音乐人腾格尔&#xff0c;再一次走进大家的视野当中&#xff0c;不过这次却不是因为唱歌。腾格尔是一个音乐人&#xff0c;他更是一个出色的球迷&#xff0c;为了表达对世界杯的喜爱&#xff0c;他还专门拍摄了段子上传网络。 说起音乐…

C++ :Symbol:符号

1&#xff1a;符号的概念 符号&#xff08;symbol&#xff09;是在 ELF格式中会遇到的概念&#xff0c;也就是在写汇编代码时候会遇到的&#xff0c;而在更高级语言&#xff08;C或者C&#xff09;中不会直接遇到这个概念&#xff0c;我们把讨论的范围限制在 Linux上的ELF格式…

python多分支选择结构实例讲解

多分支选择结构的语法格式如下&#xff1a; if 条件表达式 1 : 语句 1/语句块 1 elif 条件表达式 2: 语句 2/语句块 2 elif 条件表达式 n : 语句 n/语句块 n [else: 语句 n1/语句块 n1 ] 【注】计算机行业&#xff0c;描述语法格式时&#xff0c;使用中…

Word处理控件Aspose.Words功能演示:使用 C# 在 Word 文档中创建条形码

条形码是具有编码数据/信息的平行线、点或矩形形式的图像。行业专业人士使用条形码嵌入和访问产品信息、跟踪产品移动并跟上库存。在某些情况下&#xff0c;我们可能需要在 MS Word 文档中生成和添加条形码。MS Word 是最流行和广泛使用的图形文字处理程序。它用于创建带有文本…

总结:从实模式到保护模式的流程和相关寄存器,相关数据结构之间的联系

总结&#xff1a;从实模式到保护模式的相关寄存器和相关数据结构之间的联系 1.怎么进入保护模式 段描述符 段描述符&#xff1a; 实模式下的用户可以破坏存储代码的内存区域 &#xff0c;用段描述符来对某一段进行描述内存段类型属性来阻止这种行为。8个字节大小 全局描述…

[附源码]java毕业设计朋辈帮扶系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

HTML基础

文章目录一、HTML结构1、认识HTML标签2、HTML文件基本结构3、标签层次结构二、HTML常见标签1、注释标签2、标题标签3、段落标签4、换行标签5、格式化标签6、图片标签7、超链接标签8、表格标签9、列表标签10、表单标签12、 div & span一、HTML结构 1、认识HTML标签 HTML 代…

光点高校数据中台,助力高校信息化迎来发展新格局_光点科技

数据是教育信息化改革创新过程中的核心资产。从大数据的角度构建高校数据治理体系&#xff0c;支持高校管理信息向智能化服务和教育数字化转型&#xff0c;已成为必然趋势。 然而&#xff0c;高校拥有更大的数据规模、更复杂的数据类型、更密集的数据交换和对数据治理的需求。因…

从各大论坛收集整理的八股文手册,肝完横躺95%的Java面试岗位

今年的秋招很多小伙伴收获不错&#xff0c;拿到了心仪的offer。也有很多小伙伴屡屡碰壁&#xff0c;选择待在舒适区&#xff0c;不过没关系&#xff0c;错过了今年的金九银十&#xff0c;来年的春招再战呗&#xff01; 最近在各大论坛和社区里看见不少小伙伴慷慨地分享了常见的…

JS正则表达式

文章目录1、创建正则表达式的方式1.1、字面量形式1.2、对象2、正则方法2.1、exec()2.2、test()2.3、可以用于正则的string方法2.3.1、match()2.3.2、replace()补充&#xff1a;$在正则替换中的使用2.3.3、search()2.3.4、split()2.3.5、matchAll()3、边界量词4、模式修饰符5、原…

拷贝构造函数详解

拷贝构造函数详解1.概念与特征2.浅拷贝3.深拷贝4.拷贝构造函数典型调用场景&#xff1a;如果一个类中什么成员都没有&#xff0c;那么该类简称为空类。而空类中其实并不是真的什么都没有&#xff0c;任何类在什么都不写时&#xff0c;编译器会自动生成以下6个默认成员函数。构造…

对GROUP BY的增强

使用ROLLUP操作产生求和值使用CUBE操作产生使用GROUPING函数确定该行值是由ROLLUP或者CUBE创建的使用GROUPING SETS生成一个简单的结果集[oracleoracle-db-19c ~]$ [oracleoracle-db-19c ~]$ sqlplus / as sysdbaSQL*Plus: Release 19.0.0.0.0 - Production on Fri Nov 18 10:…

idea2022.2.3版本下载安装配置(包含运行第一个java程序教程)详细步骤

目录 一、下载idea 1.去浏览器搜索idea官网&#xff0c;找到官网 2.选择Download 3.点击左边的Download下载就好了 4.在本地磁盘建一个文件夹&#xff0c;专门用来存放idea软件的 二、安装idea 5.在本地磁盘中的下载里面找到下载的idea并双击打开 6.选择Next ​编辑 7…

【无标题】PCIe收发卡设计资料原理图:611-基于VU9P的2路4Gsps AD 2路5G DA PCIe收发卡

基于VU9P的2路4Gsps AD 2路5G DA PCIe收发卡一、板卡概述 基于XCVU9P的5Gsps AD DA收发PCIe板卡。北京太速科技该板卡要求符合PCIe 3.0标准&#xff0c;包含一片XCVU9P-2FLGA2014I、2组64-bit/8GB DDR4、2路高速AD&#xff0c; 2路高速DA&#xff0c;支持外触发&#xff…

基于单片机的学生视力保护仪

目录 摘 要 1 ABSTRACT 2 第一章 绪论 4 1.1课题的选题背景 4 1.2国内外发展现状 5 1.3本论文主要研究内容 6 1.3.1主要内容 6 1.3.2基本要求 7 第二章 学生视力保护仪总系统设计 8 2.1系统总框图 8 2.2单片机的选择 8 2.3传感器的选择 9 2.4编程语言的选择 9 第三章 系统硬件…

CentOS 7 源码制作ngnx-1.22.1-ipv6 rpm —— 筑梦之路

源码包&#xff1a;http://nginx.org/packages/centos/7/SRPMS/nginx-1.22.1-1.el7.ngx.src.rpm # 安装依赖包yum install http://mirror.centos.org/centos/7/os/x86_64/Packages/pcre2-devel-10.23-2.el7.x86_64.rpm# 安装源码包 初始化项目rpm -ivh nginx-1.22.1-1.el7.ngx…

5G无线技术基础自学系列 | 物理下行控制信道

素材来源&#xff1a;《5G无线网络优化实践》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;5G无线技术基础自学系列 | 汇总_COCOgsta的博客-CSDN博客 2.4.1 PDCCH位置定义 在LTE中&#xff0…

ESP32的AP模式使用

WifiClient 和WebServe有啥区别? (14 封私信 / 1 条消息) httpclient 和webservice有啥区别? - 知乎 (zhihu.com) 1.Webservice两大核心&#xff1a;soap&#xff08;理解为要传输的数据&#xff09;、wsdl&#xff08;理解为传输数据xml的说明&#xff09; soap xml ht…

Java类变量和类方法(static)

文章目录类变量-提出问题类变量内存布局如何定义类变量如何访问类变量类变量使用细节类方法介绍类变量-提出问题 提出问题的主要目的就是让大家思考解决之道&#xff0c;从而引出我要讲的知识点. 说:有一群小孩在玩堆雪人,不时有新的小孩加入&#xff0c;请问如何知道现在共有…

客服系统Golang源码

客服系统 概述 采用Golang语言&#xff0c;基于 gRPC [Mongo Vue3WebsocketRabbitMQ]来实现系统 用户侧逻辑采用匿名注册模式&#xff0c;Token采用JWT技术&#xff0c;服务端不保存Token信息&#xff0c;用户每次使用检测Token合法时返回新的Token来达到续期的目的 后端分…