一、认识Webpack

webpack 是一个静态的模块化打包工具,为现代的 JavaScript 应用程序;

打包 bundler:webpack 可以将帮助我们进行打包,所以它是一个打包工具 

静态的 static:这样表述的原因是我们最终可以将代码打包成最终的静态资源(部署到静态服务器);

模块化 module:webpack 默认支持各种模块化开发,ES Module、CommonJS、AMD 等;

现代的 modern:我们前端说过,正是因为现代前端开发面临各种各样的问题,才催生了 webpack 的出现和发展;

当webpack处理应用程序时,会将所有这些模块打包成一个或多个文件

比如如果出现

import './module.js'

经过webpack处理之后就会把对应的文件捞出来

webpa可以处理js/css/图片、图标字体等单位

webpack只能处理静态的,静态指的是开发过程中存在于本地的js/css/图片、图标字体等文件,就是静态的。动态的内容,webpa没办法处理,只能处理静态的

二、webpack初体验

1.npm install --save和npm install --save -dev的区别

npm install 安装依赖包 --save、–save-dev、-S、-D的区别_npm install -save-dev-CSDN博客

–save是运行时依赖,是默认的。–save -dev是开发时依赖。

像jQuery库或者Angular框架类似的,我们在开发完后后肯定还要依赖它们,否则就运行不了,这是dependencies;而写 ES6 代码,需要babel转换成es5,转换完成后,我们只需要转换后的代码,上线的时候,直接把转换后的代码部署上线,不需要babel了,上线了不需要,这就是devDependencies。而如果用了 jQuery,由于发布之后还是依赖jQuery,所以是dependencies。

webpack 的安装目前分为两个:webpack、webpack-cli它们是什么关系呢?

  • 执行 webpack 命令,会执行 node_modules 下的.bin 目录下的 webpack;
  • webpack 在执行时是依赖 webpack-cli 的,如果没有安装就会报错;
  • 而 webpack-cli 中代码执行时,才是真正利用 webpack 进行编译和打包的过程;
  • 所以在安装 webpack 时,我们需要同时安装 webpack-cli(第三方的脚手架事实上是没有使用 webpack-cli 的,而是类似于自 己的 vue-service-cli 的东西)

2.webpack的使用

①初始化项目
npm init
②安装webpack需要的包
npm install --save-dev webpack-cli@3.3.12 webpack@4.44.1
③配置webpack

编写webpack.config.js文件

const path = require('path');

module.exports = {
    //指定开发模式,不压缩编译后的文件
  mode: 'development',
  entry: './foo.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'foo.bundle.js',
  },
};
④编译并测试
npm run webpack

注意使用这个命令之前需要在package.json中配置一下

{
	"script":{
		"webpack":"webpack --config webpack.config.js"
	}
}

如果我们的配置文件并不是 webpack.config.js 的名字,而是其他的名字呢?

  • 比如我们将 webpack.config.js 修改成了 wk.config.js;

  • 这个时候我们可以通过 --config 来指定对应的配置文件;

    webpack --config wk.config.js

⑤Webpack依赖图

webpack 到底是如何对我们的项目进行打包的呢?

  • 事实上 webpack 在处理应用程序时,它会根据命令或者配置文件找到入口文件;
  • 从入口开始,会生成一个 依赖关系图,这个依赖关系图会包含应用程序中所需的所有模块(比如.js 文件、css 文件、图片、字 等);
  • 然后遍历图结构,打包一个个模块(根据文件的不同使用不同的 loader 来解析);

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三、webpack四个核心概念

1.entry和output

module.exports = {
	mode:'development',
    //单入口
    //entry:'./src/index.js',
    
    //多入口,前面的main和search是给入口取的名字,和出口[name]中的name对应
    entry:{
		main:'./src/index.js',
        search:'./src/search.js'
    },
    
    //单出口,对应只有一个入口
    //output:{
	//	path:path.resolve(__dirname, 'dist'),
    //    filename:'bundle.js'
    //}
    
    //多出口,'[name].js'是固定的写法,用[name]指定不同的入口文件对应的出口文件
    output:{
		path:path.resolve(__dirname, 'dist'),
         filename:'[name].js'
	}
}

2.loader

①什么是loader
  • loader 可以用于对模块的源代码进行转换
  • 我们可以将 css 文件也看成是一个模块,我们是通过 import 来加载这个模块的;
  • 在加载这个模块时,webpack 其实并不知道如何对其进行加载,我们必须制定对应的 loader 来完成这个功能;

loader让webpack能够去处理那些非JS文件的模块

②babel-loader

babel-loader是连接babel和loader的一个桥梁

③安装babel
npm install --save-dev babel-loader@8.1.0 @babel/core@7.11.0 @babel/preset-env@7.11.0
④配置babel-loader
module:{
	rules:{
		[
            //使用正则表达式,test配置的是需要使用到babel-loader的文件
			test:/\.js$/,
            //exclude配置的是node_modules目录下的文件都不需要使用babel-loader
			exclude:/node_modules/,
            //配置的loader是babel-loader
			loader:'babel-loader'
		]
	}
}

loader 配置方式

  • 配置方式表示的意思是在我们的 webpack.config.js 文件中写明配置信息:
  • module.rules 中允许我们配置多个 loader(因为我们也会继续使用其他的 loader,来完成其他文件的加载)
  • 这种方式可以更好的表示 loader 的配置,也方便后期的维护,同时也让你对各个 Loader 有一个全局的概览;
  • module.rules 的配置如下:
  • rules 属性对应的值是一个数组:[Rule]
  • 数组中存放的是一个个的 Rule,Rule 是一个对象,对象中可以设置多个属性:
    • test 属性:用于对 resource(资源)进行匹配的,通常会设置成正则表达式;
    • use 属性:对应的值时一个数组:[UseEntry]
    • UseEntry 是一个对象,可以通过对象的属性来设置一些其他属性
    • **loader:**必须有一个 loader 属性,对应的值是一个字符串;
    • options:可选的属性,值是一个字符串或者对象,值会被传入到 loader 中;
    • **query:**目前已经使用 options 来替代;
    • 传递字符串(如:use: [ ‘style-loader’ ])是 loader 属性的简写方式(如:use: [ { loader: ‘style-loader’} ])
  • loader 属性: Rule.use: [ { loader } ] 的简写。
⑤引入core-js

编译新增API,比如Promise类

npm install --save-dev core-js@3.6.5

使用类

import "core-js/stable"
⑥打包并测试
npm run webpack

3.plugins

①什么是plugins(插件)

loader被用于帮助webpack处理各种模块,而插件则可以用于执行范围更广的任务

详情阅读官方文档https://www.webpackjs.com/plugin@4.3.0

②html-webpack-plugin

该插件的功能就是将html文件进行处理然后和js文件一起打包

先安装

npm install --save-dev html-webpack-plugin@4.3.0
③配置html-webpack-plugin插件
const path = require('path')
//引入对应插件包
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    //设计开发模式
	mode:'development',
	entry:{
		index:'./src/index.js'
	},
	output:{
		path:path.resolve(__dirname, 'dist'),
		filename:'[name].js'
	},
    //插件配置
	plugins:[
		//单入口,template指定编译文件
		//new HtmlWebpackPlugin({
		//	template:'./3.html'
		//})
	
		//多入口
        //filename指定编译后的文件名,注意:多入口文件的时候一定要写,而且要写全称。
        //chunks指定编译后需要引入的js文件名,这里[]里面的内容和入口文件entry配置的name相对应
		new HtmlWebpackPlugin({
			template:'./index.html',
        	filename:'index.html',
        	chunks:['index']
            minify:{
            	 //删除index.html(编译后)中的注释
				removeComments:true,
            	 //删除index.html中的空格
            	 collapseWhitespace:true,
            	 //删除各种html标签属性值的双引号
            	 removeAttributeQuotes:true
        	}
		}),
         new HtmlWebpackPlugin({
			template:'./search.html',
        	filename:'search.html',
        	chunks:['search']
		})
	]
}

四、webpack的应用

1.使用webpack-dev-server搭建开发环境

​ webpack-dev-server是一个基于webpack的开发服务器,用于在开发过程中提供实时的编译和热更新功能。它能够监视文件的变化,并在文件发生改变时自动重新编译和刷新页面,从而提高开发效率。使用webpack-dev-server可以快速搭建一个本地开发环境,无需手动编译和刷新页面。它还支持代理服务器,可以将请求转发到其他服务器,方便开发时与后端进行交互。

npm install --save-dev webpack-dev-server@3.11.0

安装之后需要在webpack.config.js中进行配置

{
    "script":{
		"webpack":"webpack",
         "dev":"webpack-dev-server --open chrome"
    }
}

2.处理CSS文件

使用css-loader和style-loader, 先安装css-loader

npm install --save-dev css-loader@4.1.1

在webpack.config.js文件中完成配置

module:{
	rules:{
		test:/\.css$/,
		loader:'css-loader'
	}
}

虽然使用了css-loader,但是这时还是无法识别css文件,是因为html没有引入css文件,需要使用style标签使用css或者link标签,这时只需再使用style-loader即可

module:{
	rules:{
		test:/\.css$/,
		//loader:'css-loader'
         //运用多个loader的时候使用use.这里的use有两种写法,一种是对象式,需要配置options时候写对象式;另外一种是数组,这里使用数组更方便
         //use里面的元素要注意一下顺序,会从右往左进行解析,应该先解析css,才能把css通过style标签嵌入html中
         use:['style-loader', 'css-loader']
	}
}

上述的style-loader只是一种方法,还可以生成link标签,需要使用插件mini-css-extract-plugin

详细方法看文档MiniCssExtractPlugin | webpack 中文文档 | webpack中文文档 | webpack中文网 (webpackjs.com)

先安装

npm install --save-dev mini-css-extract-plugun@0.9.0

在配置文件webpack.config.js文件中完成配置

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  plugins: [new MiniCssExtractPlugin()],
  module: {
    rules: [
      {
        test: /\.css$/i,
        //MiniCssExtractPlugin提供的一个loader方法
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
    ],
  },
};

3.处理图片

如果是外部的资源,是不需要考虑webpack的,只有本地的图片才需要被webpack处理

①使用file-loader处理CSS中的图片

先安装

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

在配置文件webpack.config.js文件中完成配置

module:{
	rules:[
		{
			test:/\.css$/,
			use:[
				{
					loader:MiniCssExtractPlugin.loader,
					options:{
						//指定复制图片的位置
						publicPath:'../'
					}
				},
				'css-loader'
			]
		},
        {
			test:/\.(jpg|png|gif)$/,
			use:{
				loader:file-loader,
				options:{
					//指定图片编译后的文件名以及路径,[name]对应图片原来的名字,和entry中的name无关
                      //[ext]表示保持图片原来的扩展名
					name:'img/[name].[ext]'
				}
			},
        }
	]
}

使用file-loader之后的变化:

图片得到复制、css中图片的url发生变化,一般默认是在当前目录下,但是图片复制不在当前目录下,有两种解决方法:一种是指定图片复制的路径,解决方法如上代码;另外一种是指定css文件中图片的路径,解决方法如上代码。

②使用html-withimg-loader处理html中的图片

用途:我们在编译图片时,都是使用file-loaderurl-loader,这两个loader都是查找js文件里的相关图片资源,但是html里面的文件不会查找所以我们html里的图片也想打包进去,这时使用html-withimg-loader

安装:

npm install --save-dev html-withimg-loader@0.1.16

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>首页</title>
</head>
<body>
    <img src="./src/img/pic.jpg" alt="">
</body>
</html>

在webpack.config.js中完成配置:

如果打包出现img的src路径为[Object Module](路径为一个对象默认模块化导入),解决方案有

  • 将file-loader降级到4.2.0
  • 修改options参数esModule为false
module.exports = {
    module: {
        rules: [
            {
                test: /\.(png|jpg|jpeg)$/,
                use: {
                    loader: "file-loader",
                    options: {
                        name: "img/[name].[ext]",
                        esModule: false
                    }
                }
            },
            {
                test: /\.(htm|html)$/,
                use: "html-withimg-loader"
            }
        ]
    }
}

html-withimg-loader只是处理html中的图片,不能处理具体的图片路径问题,所以要和file-loader搭配使用

③使用file-loader处理JS中的图片

配置文件:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
 
module.exports = {
  mode: 'development',
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
            options: {
              publicPath: '../'
            }
          },
          'css-loader'
        ]
      },
      {
        test: /\.(jpg|png|gif)$/,
        use: {
          loader: 'file-loader',
          options: {
            name: 'img/[name].[ext]'
          }
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html',
      filename: 'index.html'
    }),
    new MiniCssExtractPlugin({
      filename: 'css/[name].css'
    })
  ]
};

index.js:

import './index.css';
 
// 导入图片的地址
import img from './img/logo.png';
 
console.log(img);
 
const imgEl = document.createElement('img');
imgEl.src = img;
document.body.appendChild(imgEl);
④使用url-loader处理图片

用途:url-loader也是处理图片类型资源,只不过它与file-loader有一点不同,url-loader可以设置一个根据图片大小进行不同的操作,如果该图片大小大于指定的大小,则将图片进行打包资源,否则将图片转换为base64字符串合并到js文件里

先安装:

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

在webpack.config.js中完成配置

module.exports = {
    module: {
        rules: [
            {
                test: /\.(png|jpg|jpeg)$/,
                use: [
                    {
                        loader: "url-loader",
                        options: {
                            name: "[name]_[hash:8].[ext]",
                            limit: 10240, // 这里单位为(b) 10240 => 10kb
                            // 这里如果小于10kb则转换为base64打包进js文件,如果大于10kb则打包到dist目录
                        }
                    }
                ]
            }
        ]
    }
}

中完成配置

module.exports = {
    module: {
        rules: [
            {
                test: /\.(png|jpg|jpeg)$/,
                use: [
                    {
                        loader: "url-loader",
                        options: {
                            name: "[name]_[hash:8].[ext]",
                            limit: 10240, // 这里单位为(b) 10240 => 10kb
                            // 这里如果小于10kb则转换为base64打包进js文件,如果大于10kb则打包到dist目录
                        }
                    }
                ]
            }
        ]
    }
}

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐