1.What is webpack?
我们在学习一门新的技术之前,需要事先了解你学习的是一个什么,为什么要学习它,掌握了它给我们带了什么帮助可以为我们做哪些事情,接下来让我们认识一下webpack。
百度百科解释:webpack 是代码编译工具,有入口、出口、loader 和插件。webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时,它会在内部构建一个依赖图(dependency graph),此依赖图对应映射到项目所需的每个模块,并生成一个或多个 bundle。
webpack官网解释:本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
个人对webpack的理解:webpack就类似一条加工厂线,可以将一个原始材料加工,然后变成成品出库。webpack的工作就类似这种场景,我们可以使用webpack里面的各种loader,plugin,进行代码的编译,压缩,分割,做兼容性的处理兼容更低版本的浏览器,提升代码的性能,提升用户的体验等等。然后通过webpack打包出来的资源就可以部署到服务器。
2.webpack模式的介绍。
webpack本身的功能是非常有限的,这跟我们玩游戏一样不买装备输出伤害是不够的,webpack也是一样我们仅仅使用webpack的自身带的功能是不够的
开发模式下:webpack只能编译JS中的ES Module语法,在开发模式下webpack主要为我们做两件事情,编译代码,让浏览器能识别运行我们的代码。代码质量的检查,树立代码规范。
生产模式下:webpack做了小小的升级,不仅能编译JS中的ES Module语法,还能对js代码进行压缩。
// 在webpack.config.js中配置对象中配置mode属性'development'开启开发模式'production'开启生产模式
module.exports = {
mode: 'production'
};
体验一下development与production模式的区别,废话不多说上demo
//创建一个webpack_basic文件夹,在webpack_basic目录下创建一个src,src里面有一个入口文件main.js和js目录
/**
* @directory ../src/js/cumulative
* @params {*} args
* @return number
*/
export const cumulative = (...args)=>{
return args.reduce((pre,value)=>{
return pre+value;
})
}
/**
* @directory ../src/js/extend.js
* @param {function} sub
* @param {function} sup
*/
// 使用原型工厂封装继承
export const extend = (sub,sup)=>{
sub.prototype = Object.create(sup.prototype);
sub.prototype.construct = sub;
Object.defineProperty(sub.prototype,'construct',{
value:sub,
enumerable:false // 禁止遍历construct
})
}
/**
* @directory ../src/main.js
*/
import {cumulative} from './js/cumulative'
import {extend} from './js/extend'
let total = cumulative(1,2,3,4,5,6);
User.prototype.show = function(){
return `${this.name}今年${this.age}岁啦`;
}
function User(){
this.name='tianlihard';
this.age=24;
}
function Admin(){
this.name='studyWebpack';
this.age=1;
}
extend(Admin,User)
const hd = new Admin();
console.log(hd.show());
console.log(total)
//===========在public目录下创建index.html============
webpack 基础
Webpack
我们在不使用webpack对代码编译在浏览器运行会报错,因为浏览器是不识别ES Module语法。报错信息如下:
解决报错:
1.初始化一个pack.json文件,执行npm init -y。注意:文件名不能是webpack,文件夹避免中文字避免不必要的报错。
2.安装webpack和webpack-cli,执行npm i webpack webpack-cli -D。
3.执行打包命令 npx webpack ./src/main.js --mode=development
按照以上的步骤操作我们可以发现在根目录下生成了一个dist文件里面有一个main.js文件这就是webpack帮我们打包出来的文件,我们在将index.html文件里面的js代码引入的修改成打包之后的main.js。
对比development模式与production模式下打包生成的文件大小:
1.执行npx webpack ./src/main.js --mode=development生成的main.js文件的大小大概6KB
2.执行npx webpack ./src/main.js --mode=production生成的main.js文件的大小大概1KB
总结:webpack在production模式下确实不仅能对js代码进行编译,还能对js代码进行压缩,使得体积更小。
3.webpack配置。
webpack配置主要可以划分五个模块:
1.entry:打包入口的文件的配置,指示webpack从哪一个或者多个文件开始打包。
2.ouput:打包输出的文件配置,指示webpack输出一个或者多个bundle。
3.loader:加载器,webpack本身只能处理js,json等资源,其他的资源处理需要借助loader完成。
4.plugin:插件,扩展webpack的功能。
5.mode:模式,文章上面已经对模式有所介绍。
4.样式资源的处理
webpack本身是不能处理css样式资源的,所以我们需要借助loader去完成css资源的处理。
1.安装css-loader npm i css-loader style-loader -D
2.webpack配置
/**
* @directory ../webpack.config.js
*/
const path = require('path'); // node里面的核心模块path,专门用来处理文件路径的问题
module.exports = {
// 入口
entry: './src/main.js',
// 输出
output: {
// 文件的输出路劲,绝对路径,__dirname是node.js中的一个变量,表示当前文件夹所在的文件目录
path: path.resolve(__dirname,"dist"),
// 入口文件输出文件名
filename: 'main.js'
},
// loader
module: {
rules: [
{
test: /\.css$/, //只检测以css结尾的文件
// loader执行的顺序是从右边到左,css-loader作用将css代码编译成commonjs模块插入到js中 style-loader动态的创建style标签将css代码加到html中
use: ['style-loader','css-loader']
}
]
},
// plugin
// 模式
mode:'development'
}
webpack本身也不能对css预处理器less,scss和stylus进行处理
1.安装npm i less less-loader sass sass-loader stylus-loader -D
2.webpack配置
/**
* @directory ../webpack.config.js
*/
const path = require('path'); // node里面的核心模块path,专门用来处理文件路径的问题
module.exports = {
// 入口
entry: './src/main.js',
// 输出
output: {
// 文件的输出路劲,绝对路径,__dirname是node.js中的一个变量,表示当前文件夹所在的文件目录
path: path.resolve(__dirname,"dist"),
// 入口文件输出文件名
filename: 'main.js'
},
// loader
module: {
rules: [
{
test: /\.css$/, //只检测以css结尾的文件
// loader执行的顺序是从右边到左,css-loader作用将css代码编译成commonjs模块插入到js中 style-loader动态的创建style标签将css代码加到html中
use: ['style-loader','css-loader']
},
{
test:/\.less$/,
use:['style-loader','css-loader','less-loader']
},
{
test:/\.s[ac]ss$/,
use:['style-loader','css-loader','sass-loader']
},
{
test:/\.styl$/,
use:['style-loader','css-loader','stylus-loader']
}
]
},
// plugin
// 模式
mode:'development'
}
5.图片资源的处理
过去的webpack4时,我们处理图片资源通过file-loader和url-loader进行处理,现在webpack5已经将这两个loader内置到webpack里面了,我们只需要简单的配置即可处理图片资源。
/**
* @directory ../webpack.config.js
*/
module.exports = {
// loader
module: {
rules: [
// 对图片资源处理
{
test:/\.(png|jpe?g|svg|gif|webp)$/,
type:'asset',
parser:{
dataUrlCondition:{
// 配置小于10KB的图片转化为base64字符串,减少http的请求次数;图片太多不适合转化为base64,图片的体积增加的太大了。
maxSize:10 * 1024 // 10KB
}
}
}
]
},
}
6.修改输出目录的结构
修改输出目录的结构的目的是为了,将我们打包的资源进行一个分类,方便管理。
/**
* @directory ../webpack.config.js
*/
const path = require('path'); // node里面的核心模块path,专门用来处理文件路径的问题
module.exports = {
// 入口
entry: './src/main.js',
// 输出
output: {
// 文件的输出路劲,绝对路径,__dirname是node.js中的一个变量,表示当前文件夹所在的文件目录
path: path.resolve(__dirname,"dist"),
// 入口文件输出文件名
filename: 'static/js/main.js'
},
// loader
module: {
rules: [
// 对图片资源处理
{
test:/\.(png|jpe?g|svg|gif|webp)$/,
type:'asset',
parser:{
dataUrlCondition:{
// 配置小于10KB的图片转化为base64字符串,减少http的请求次数;图片太多不适合转化为base64,图片的体积增加的太大了。
maxSize:10 * 1024 // 10KB
}
},
// [hash:10]是表示取哈希值前面10位 [ext]继承扩展名
generator:{
filename:"static/madie/[hash:10][ext][query]"
}
}
]
},
}
7.在打包前清空dist目录
/**
* @directory ../webpack.config.js
*/
const path = require('path'); // node里面的核心模块path,专门用来处理文件路径的问题
module.exports = {
// 输出
output: {
// 文件的输出路劲,绝对路径,__dirname是node.js中的一个变量,表示当前文件夹所在的文件目录
path: path.resolve(__dirname,"dist"),
// 入口文件输出文件名
filename: 'static/js/main.js',
// 在下次打包之前,清空dist整个文件目录
clean:true
},
}
8.字体图标资源的处理
/**
* @directory ../webpack.config.js
*/
const path = require('path'); // node里面的核心模块path,专门用来处理文件路径的问题
module.exports = {
// loader
module: {
rules: [
{
test:/\.(ttf|woff2?)$/,
type:'asset/resource',
generator:{
filename:"static/fonts/[hash:10][ext][query]"
}
}
]
},
}
9.js代码的处理。
为什么还需要处理js代码,是因为webpack本身对js的处理是非常有限的,webpack本身只能对ES模块的语法进行处理,并不能编译es6的其他的新增语法,导致我们应用程序不能兼容更多的浏览器。处理这个问题需要借助babel-loader来对我们js代码进行编译。在对js代码编译之前,为了保证开发出来的代码质量我们和代码的健壮性,我们需要使用eslint对代码进行检测,这样就不需我们开发的人员使用肉眼去检测我们的代码。eslint可以对javascript和JSX语法进行检测。
eslint的介绍和使用:eslint是可组装的javascript和jsx检查工具。
1.eslint的配置文件的写法有很多种,.eslintrc.js是其中的一种,不同的配置文件命名的方式,只有写配置的格式不同。
2.eslint里面的rules是通过0(off),1(warn),2(error)来决定是否开启或者提示警告,或者报错。rules里面的规则的优先级高于extend里面的规则。
3.extend继承,因为eslint的配置规则是非常多的,我们没有必要全部一条一条的自己去写,我们npm下载相关的规则库,我们通过extend继承即可。eslint官方规则(eslint:recommended是不需要下载的),Vue cli官方规则(plugin:vue/essential),React cli官方的规则:react-app(react-app)
4.eslint的使用:eslint的安装npm i eslint-webpack-plugin eslint -D,然后再eslint插件的引入,const ESLintPlugin = require('eslint-webpack-plugin');再到plugins模块中使用eslint插件。
// webapck中的配置
const ESLintPlugin = require('eslint-webpack-plugin');
const path = require("path");
module.exports={
plugins:[
new ESLintPlugin ({
// 指定只检测src下面的文件
context:path.resolve(__dirname,"src")
})
]
}
// .eslintrc.js文件下的配置
module.exports={
// 继承eslint的规则
extends:["eslint:recommended"],
env:{
node:true,// 启用node中的全局变量
browser:true,// 启用浏览器中的全局变量
},
parserOptions:{
ecmaVersion:6,
sourceType:"module",
},
// rules中的规则优先级高于extends继承下来的规则
rules:{
"no-var":2 // 不能使用var定义变量
}
}
// .eslintignore,主要配置哪些文件不需要通过eslint检测
dist
eslint插件可以配合vscode里面的插件一起使用,这样我们再编写代码时不符合规范的代码就会给我们报错提示,不用到打包的时候才报错。
babel-loader的介绍和使用:Babel主要是javascript的编译器,主要用于将es6语法编写的代码转换为向后兼容的javascript语法。以便能够运行在当前和旧版本的浏览器环境或其他环境中。
1.npm i babel-loader @babel/core @babel/preset-env -D安装babel
2.在webpack.config.js中配置
module.exports={
rules:[
{
test:/\.js$/,
exclude:/node_modules/, // 排除node_modules里面的不进行编译
loader:"babel-loader",
}
]
}
3.设置babel.config.js里面的配置只要通过babel的智能预设来处理es6的语法
moudle.exports={
presets:["@babel/preset-env"]
}
10.处理html资源。
html的资源处理主要是通过html-webpack-plugin插件来处理html资源,以public文件下的html文件为模板生成一个新的html,有两个特点与原来的html的结构一样,自动引入js文件。
1.npm i html-webpack-plugin -D安装插件
2.在webpack中配置插件
// 在webpack.config.js中配置html-webpack-plugin插件
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports={
plugins:[
new HtmlWebpackPlugin({
// 以public/index.html为模板生成一个新的html文件
template:path.resolve(__dirname,"public/index.html")
})
]
}
11.开发服务器的自动化。
没有开发服务器自动化,我们每一次改动代码都需要重新执行npx webpack进行代码打包操作才能看到改了之后的效果。使用开发服务器就很好的解决了这个问题,给开发者带来了非常大的便利。
1.npm i webpack-dev-server -D
2.在webpack.config.js中配置开发服务器。
// webpack.config.js
module.exports={
devServe:{
host:'localhost',// 启动服务器的域名
port:"3000", // 启动服务器的端口
open:true, // 是否自动打开浏览器
}
}
注意点:开发服务器是没有任何输出的,它是在内存中打包编译的一个过程
webpack基础完结~~