webpack4的学习

webpack是个前端资源加载/模块打包器,将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源文件。
官网:https://webpack.js.org/
在这里插入图片描述

1. 安装webpack4

(1)webpack4 需要的node版本最低为8.9.4,所以建议把node升级为9以上。
(2)安装webpack和webpack-cli
命令:
npm install webpack -g
npm install webpack-cli -g
在写这篇文章的时候 我用的webpack版本为@4.35.0 webpack-cli的版本为@3.3.5

2. 基本使用

2.1 基础用法

我们在文件夹下新建两个文件 index.js 和 hello_module.js。
在这里插入图片描述
其中文件的内容分别为:

//hello_module.js
let obj = {
	sayHello:function(){
		console.log("hello");
	}
}

module.exports = obj
//index.js
let f1 = require('./hello_module.js').sayHello;

f1()

可以看出index.js依赖于hello_module.js这个模块。
使用node运行index.js如下所示
在这里插入图片描述
我们试着把这两个文件进行打包。所以我们可以设置index.js为入口文件。
基本打包命令:webpack 入口文件名 -o 出口文件名
在这里插入图片描述
打包出来可以看到文件夹下出现了output.js这个文件
在这里插入图片描述
使用node运行output.js可以看到也成功的打印Hello了
在这里插入图片描述
但是我们在打包的时候会看到一个提示:mode模式还没有选择。如果没有设置webpack将默认选择为production生产模式。
在这里插入图片描述
我们来看看production(生产模式)和development(开发者模式)的webpack打包 有什么不同呢~
在这里插入图片描述
我们使用上面的命令行以开发者模式打包出来了output_dev.js
在这里插入图片描述
我们可以看到打包出来两个文件大小,开发者模式的明显要比生产模式的大。其实是开发者模式为我们提供了一些功能,我们会在后面具体分析~

2.2 零配置文件用法

webpack4的新特性支持零配置文件打包。换句话说,就是不需要配置打包的入口/出口文件了。默认的入口文件地址为src/index.js,默认的出口文件地址为dist文件夹。
我们来验证一下:

在src文件夹中放入了这两个文件,并在test2文件夹中执行webpack
在这里插入图片描述
可以看到,在test2文件夹下生成了dist文件夹,打包文件为main.js
在这里插入图片描述
执行node命令依然打印出了 hello,即说明也打包成功了~
在这里插入图片描述
但其实我们真正的工程项目中,配置文件是必不可少的。下面我们来学习一下webpack的配置文件。

2.3 webpack配置文件

2.3.1 基础配置

webpack的基础配置要写在webpack.config.js中,而最基础的是在其中设置webpack打包的入口、出口地址。其基本配置如下

//webpack.config.js
const path = require('path');
module.exports = {
   entry:'./input.js', //当前入口文件
   output:{
   	path:path.resolve(__dirname,'dist'),
   	filename:'ouput.bundle.js'
   }
};

在工程中,我们往往需要多入口文件打包。而配置文件中的entry支持我们传入一个对象。

const path = require('path');
module.exports = {
   entry:{
   	home:'./home.js',
   	about:'./about.js',
   	other:'./other.js'
   },
   output:{
   	path:path.resolve(__dirname,'dist'),
   	filename:'[name].bundle.js' //这个name将自动打包为homg/about/other
   }
};

入口的三个文件分别为:

//home.js
const home = function(){
   console.log("home");
}
//about.js
const about = function(){
   console.log("about");
}
//other.js
const other= function(){
   console.log("other");
}

我们来尝试一下 使用webpack.config.js来进行模块打包,在test3文件夹中运行webpack,可以看到在dist文件中,打包出了三个文件。
在这里插入图片描述
我们随便选一个打包出来的文件去查看时,会发现console.log都没有被打包进去。这是由于我们默认的打包模式为production(生产模式),会自动进行tree shaking我们在配置文件中可以设置打包模式

const path = require('path');
module.exports = {
   entry:{
   	home:'./home.js',
   	about:'./about.js',
   	other:'./other.js'
   },
   output:{
   	path:path.resolve(__dirname,'dist'),
   	filename:'[name].bundle.js' //这个name将自动打包为homg/about/other
   },
   mode:"development" //设置模式为开发者模式。
};

这时候打包出来的代码中就能看到console.log了。这就是生产者模式和开发者模式的另一区别。

3. 加载器Loader

loader是webpack用来预处理源文件的。比如说我们的源文件是typescript、图片等,都需要使用loader来讲其转换为浏览器可以执行的js文件。可用的loader有很多,在https://webpack.js.org/loaders/ 中都可以找到。以下我就简单介绍几种loader的用法

3.1 url-loader

功能:当文件的大小小于某个指定的大小的时候,会将文件转换成DataURL的形式,即base64形式。
用途:由于每一个网页可能都会有一些很小的图标图片,如果将这些小的图标都单独打包的话,需要发送许多次请求,使页面加载缓慢。很早之前的做法是使用雪碧图,现在我们可以使用url-loader将这些图标转换成base64的形式,存放在js文件中。

使用url-loader首先需要在webpack.config.js文件中添加下面的代码

module:{
	rules:[
		{
			test:/\.(png|jpg|gif)$/i, //正则匹配由png jpg gif格式的文件
			use:[
				{
					loader:'url-loader', //使用url-loader为这些文件进行打包
					options:{
						limit:8192 //限制文件的大小在8k以下
					}
				}
			]
		}
	]
}

我们来看看实际的例子吧~test4中,文件结构如图。
在这里插入图片描述
且注意一下test1,test2的文件大小。test1大于8k,test2小于8k。
在这里插入图片描述
input.js的内容为:

const good = "hello";

import img1 from './img/test1.jpg'
import img2 from './img/test2.jpg'

webpack.config.js的内容为:

const path = require('path');
module.exports = {
	entry:"./input.js",
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'output.bundle.js' 
	},
	mode:"development", //设置模式为开发者模式。
	module:{
	rules:[
		{
			test:/\.(png|jpg|gif)$/i, //正则匹配由png jpg gif格式的文件
			use:[
				{
					loader:'url-loader', //使用url-loader为这些文件进行打包
					options:{
						limit:8192 //限制文件的大小在8k以下
					}
				}
			]
		}
	]
}
};

我们试着执行webpack命令
在这里插入图片描述
当然是会报错的,因为我们使用了url-loader却没有安装它。我们先使用npm init -y生成一个package.json文件
在这里插入图片描述
然后使用npm install url-loader -S 安装url-loader并且将其写入配置文件中(-S的作用)。
在这里插入图片描述
我们可以看到package.json中添加了一行 “url-loader“ : "^2.0.0"
由于url-loader还需要以来file-loader,所以我们再执行 npm install file-loader -S来安装file-loader
在这里插入图片描述
这样,file-loader和url-loader都被成功的安装并配置了。这时再执行webpack命令,就可以成功的打包了。
在这里插入图片描述
打包出来的dist文件中,我们只能看到一张图片。可我们明明打包的是两张图片呀?
在这里插入图片描述
原因是什么呢?因为我们在webpack.config.js中设置的限制文件大小为8k以下。也就是说,在8k以下的test2.jpg被打包成了base64编码在js文件中而8k以上的test1.jpg打包成了单独的文件
打开打包好的文件output.bundle.js我们也能看到这样的结果~
在这里插入图片描述

3.2 babel-loader

功能:将ES6、ES7的语法转换成ES5的语法。
用途:因为有些低版本的浏览器对ES6语法的支持比较低。如果不使用babel进行打包的话将不能实现正常功能。

与url-loader一样,使用babel-loader也需要在webpack.config.js中添加下列代码:

module:{
	rules:[
		{
			test:/\.m?js$/, //正则匹配.js格式的文件
			exclude:/(node_modules|bower_components)/, //排除掉一些文件夹
			use:[
				{
					loader:'babel-loader', //使用babel-loader为这些文件进行打包
					options:{
						presets:['@babel/preset-env'] //某些使用的规则
					}
				}
			]
		}
	]
}

我们来看看实际的例子,在test5中,文件的结构如图。(记得使用npm init -y生成一个package.json文件)
在这里插入图片描述
安装:我们使用npm install -D babel-loader @babel/core @babel/preset-env webpack 安装babel-loader
安装后的package.json文件会出现这样:
在这里插入图片描述
其中,input.js文件内容如下:

async function sayHello(){
	const result = await fetch('https://www.baidu.com');
	console.log(result);
}
sayHello();

如果配置文件没有加上babel-loader的rules。使用webpack打包后的文件,我们去搜索fetch,可以发现ES6的语法依然在。这在版本较低的浏览器上是没有办法处理的。
在这里插入图片描述
我们试着添加一下babel-loader的rules
webpack.config.js文件内容如下:

const path = require('path');
module.exports = {
	entry:"./input.js",
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'output.bundle.js' 
	},
	mode:"development", //设置模式为开发者模式。
	module:{
	rules:[
		{
			test:/\.(png|jpg|gif)$/i, //正则匹配由png jpg gif格式的文件
			use:[
				{
					loader:'url-loader', //使用url-loader为这些文件进行打包
					options:{
						limit:8192 //限制文件的大小在8k以下
					}
				}
			]
		},
		{
			test:/\.m?js$/, //正则匹配.js格式的文件
			exclude:/(node_modules|bower_components)/, //排除掉一些文件夹
			use:[
				{
					loader:'babel-loader', //使用babel-loader为这些文件进行打包
					options:{
						presets:['@babel/preset-env'] //某些使用的规则
					}
				}
			]
		}
	]
}
};

那么我们现在来使用webpack对input.js进行打包
最终在打包生成的output.bundle.js文件中,我们已经找不到async await这些ES6中才出现的语法了。
在这里插入图片描述

3.3 sass-loader

功能:将sass/scss文件转换为css文件
与上面的步骤相同。就不细说了。
安装
我们使用npm install sass-loader node-sass -D 安装sass-loader
我们使用npm install style-loader css-loader -D 安装sass-loader

与url-loader一样,使用babel-loader也需要在webpack.config.js中添加下列代码:

module:{
	rules:[
		{
			test:/\.scss$/, //正则匹配.js格式的文件
			use:[
				"style-loader"
				"css-loader"
				"sass-loader"
			]
		}
	]
}

4. 插件Plugin

4.1 MiniCss

安装:npm install mini-css-extract-plugin -D
在配置文件中引入: const MiniCssExtractPlugin = require(“mini-css-extract-plugin”);
在webpack.config.js中引入下面的语句:(rules里有所变化,注意!)

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
	plugins:[
		new MiniCssExtractPlugin({
			filename:"[name].css", //name就是entry的键名
			chunkFilename:"[id].css"
		})
	],
	rules:[
		{
			test:/\.scss$/,
			use:[
				process.env.NODE_ENV !== 'production' ? 'style-loader': MiniCssExtractPlugin.loader,
			]
		}
	]
}

这样会在开发者模式中,将css单独打包成一个.css文件,更好的分离代码。避免bundle文件非常的大,也便于开发时debug。

4.2 DefinePlugin

通常我们在项目中会有两个环境:生产环境和开发环境。不同的环境中需要配置不同的需求,如访问不同的服务器地址等。这时候就可以使用DefinePlugin来设置服务器地址为一个变量,在写代码时只使用这一个变量即可。如:

new webpack.DefinePlugin({
	'SERVICE_URL':JSON.stringify('http://www.baidu.com')
});

我们来试一试吧~
在test6文件夹中,文件的结构是这样的
在这里插入图片描述
其中,input.js内容为:

async function sayHello(){
	const result = await fetch(SERVICE_URL);
	console.log(result);
}
sayHello();

webpack.config.js内容为:

const path = require('path');
const webpack = require('webpack')
module.exports = {
	entry:"./input.js",
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'output.bundle.js' 
	},
	mode:"development", //设置模式为开发者模式。
	plugins:[
		new webpack.DefinePlugin({
			'SERVICE_URL':JSON.stringify('http://www.baidu.com')
		})
	]
};

我们使用webpack进行打包后,文件的结构是这样的:
在这里插入图片描述
我们打开打包后的文件可以看到SERVICE_URL已经被替换成为了http://www.baidu.com。这样能够方便我们修改一些变量,而不影响整个工程。
在这里插入图片描述
(这应该还要加上babel转ES6语法,但我做的时候忘了。。)

4.3 HtmlWebpackPlugin

由于浏览器中,js文件不能单独运行,所以需要将打包好的js文件搭载在html文件中执行。HtmlWebpackPlugin就给我们提供了这样一个功能。
安装:npm install html-webpack-plugin -D
并对webpack.config.js进行如下的修改:

 const HtmlWebpackPlugin = require('html-webpack-plugin');
 module.exports = {
 	plugins:[new HtmlWebpackPlugin()] //在plugin中添加这一段代码
 }

这样执行webpack就会生成一个index.html,自动帮我们引入打包好的css和js文件。
我们来尝试一下~
在上一个test6的基础上,我们将webpack.config.js文件修改成如下:

const path = require('path');
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
	entry:"./input.js",
	output:{
		path:path.resolve(__dirname,'dist'),
		filename:'output.bundle.js' //这个name将自动打包为homg/about/other
	},
	mode:"development", //设置模式为开发者模式。
	plugins:[
		new webpack.DefinePlugin({
			'SERVICE_URL':JSON.stringify('http://www.baidu.com')
		}),
		new HtmlWebpackPlugin()
	]
};

其余不变,现在我们执行webpack命令进行打包。文件的结构变成了这样:
在这里插入图片描述
再打开这个新生成的index.html文件,会发现他自动帮我们引入了打包好的js文件。
在这里插入图片描述
当然,生成的html文件我们也是可以自己做一些定义的。比如生成的标题等等。可以在下面的官方文档中查询
https://webpack.js.org/plugins/html-webpack-plugin/
https://github.com/jantimon/html-webpack-plugin
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值