由于对于webpack的各项配置不是太熟悉,用到了都是百度抄作业,就想系统的学习一下,在b站找了学习视频,视频讲的很详细就做了做笔记。
关于我的学习笔记
我的webpack学习之路(webpack基础开发配置) 我的webpack学习之路(关于webpack的性能优化) 我的webpack学习之路(webpack配置详解)
webpack设置一个入口文件
通过入口文件形成依赖关系图,根据先后顺序引入资源
形成chunk (代码块)
chunk根据不同资源进行不同处理
这个处理过程叫打包
打包完成后输出的文件为bundle
Entry
入口(Entry)指示Webpack以哪个文件为入口起点开始打包,分析内部依赖图
Ouput
输出(Ouput)指示webpack打包后的资源bundles输出到哪里去,以及如何命名
Loader
Loader让Webpack能够出处理那些非JavaScript文件(webpack自身只理解JavaScript)
类似翻译官,将英文,日文等翻译成中文,这样中国人就能看懂了
Plugins
插件(Plugins)可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量等
loader类似翻译官的工作,如果让他去开飞机,开大炮,疏通下水管道,它是做不了的。需要一些专业的人来做。而webpack就是将这些交给插件(开飞机的插件、开大炮的插件、疏通下水道插件)来做
Mode
模式(Mode)指示Webpack使用相应模式的配置
选项描述特点development(开发)会将process.env.NODE_ENV的值设为development。启用NamedeChunksPlugin和NamedModulesPlugin。能代码本地调试运行的环境production(生产模式)会将process.env.NODE_ENV的值设为production。启用FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenation,NoEmitOnErrorsPlugin, OccurrenceOrderPlugin,SideEffectFlagPlugin和 UgligyJsPlugin能让代码优化上线运行的环境全局安装webpack
npm i webpack webpack-cli -g在本地安装
npm i webpack webpack-cli -D 根目录 ---build ---node_modules ---src |---index.js ---packages-lock.json ---packages.json // index.js // webpack入口文件 /* 1.运行指令 开发环境:webpack ./src/index.js -o ./build/built.js --mode=development wabpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js 整体打包环境是开发环境 生产环境:webpack ./src/index.js -o ./build/built.js --mode=production wabpack会以 ./src/index.js 为入口文件开始打包,打包后输出到 ./build/built.js 整体打包环境是生产环境 2.结论 1.webpack能处理js/json,不能处理css/img等资源 2.生产环境和开发环境将ES6模块化编译成浏览器能识别的模块化~ 3.生产环境比开发环境多一个压缩js代码 */新建一个文件
根目录 ---src ---index.css ---index.js首先在index.css写如一些css样式
body,html { margin: 0; padding: 0; background-color: pink; }在index.js引入index.css
// 引入样式资源 import './index.css'这里webpack不能打包css样式,需要借助loader(帮助webpack解析它不能识别的模块),使用loader就必须定义配置文件
这里在根目录下定义配置文件,新建一个webpack.config.js文件,与src同层级
/* webpack.config.js webpack的配置文件 作用:指示webpack 干那些活(当你运行webpack指令的时候,会加载里面的配置,以里面的配置来干活) 所有的构建工具都是基于Nodejs平台运行的~模块化默认采用commomjs。 src是写项目代码 用的ES6模块化 webpack是写配置代码 基于node平台,所以用的commonjs模块化 这两个是两方面 */ const { resolve } = reuqire('path') // 引入nodejs的path模块,通过解构赋值来提取reslove // resolve是一个专门处理(拼接)绝对路径的一个方法 // commonjs 的 module.exports 去暴露一个对象 module.exports = { // webpack配置 // 先写入上面五个核心配置 entry: './src/index.js', // 入口起点 指示从./src/index.js开始打包 output: { // 输出 注意:输出是一个对象,有两个属性 filename: 'build.js', // 输出的文件名 /* path: ''输入的路径 这里输出的build文件下面, 需要在src同层级下新建一个build文件夹 通常来讲这里会写个绝对路径(避免出错),需要借助node的一个核心模块path __dirname:nodejs的变量,代表当前文件(webpack.config.js)的目录的绝对路径(这里webpack路径就是 ./根目录) */ path: resolve(__dirname,'build') // 输出到webpack.config.js路径的build文件夹下面(./根目录/build) }, // laoder配置 module: { rules: [ // 详细的loader配置 ] }, // plugins的配置 plugins: [ // 详细plugins的配置 ], // 模式 mode: 'development' // 开发模式 // mode: 'production' // 生产 }以上就做了一个简单的配置搭建,还不能处理css样式,需要使用一个东西css-loader
如何使用
// webpack.config.js // laoder配置 module: { rules: [ { // 匹配那些文件 通常使用正则匹配 test: /\.css$/, // 匹配文件名以.css结尾,会遍历所有文件,一旦发现.css文件就会进行处理 // 使用use进行处理,使用那些loader进行处理 use: [ // use数组中loader执行顺序:从右到左,从下到上依次执行 // 处理样式文件需要以下两个loader 'style-loader', // 创建一个style标签,将js中的样式资源插入进去,添加到head中生效 'css-loader' // 将css文件变成commonjs模块加载js中,里面的内容是样式字符串 ] } ] },配置完成后下载依赖
首先我在根目录下npm init,初始化一个包描述文件
然后下载weback和webpack-cli开发依赖
npm i webpack webpack-cli -D再下载style-loader和css-loader依赖
npm i style-loader css-loader -D依赖下载完成后运行webpack命令,就会开始打包
webpack在这里我运行webpack时报错
webpack : 无法将“webpack”项识别为 cmdlet、函数、脚本文件 或可运行程序的名称。请检查名称的拼写,如果包括路径,请确 保…
我的解决办法是将webpack和wabpack-cli全局安装,在运行webpack命令就顺利打包了
npm install webpack -g npm install webpack-cli -g运行完成之后,在build文件夹下会多出一个build.js文件
在build.js中会看到如上所示,写的样式,css-loader 将其变成commonjs模块加载js中,里面的内容是样式字符串
这时在build文件夹中添加一个index.html文件,引入build.js,在浏览器中的打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="./build.js"></script> </body> </html>这就是’style-loader’的作用: 创建一个style标签,将js中的样式资源插入进去,添加到head中生效
以上就是简单的webpack打包样式
上面处理样式资源时使用的是loader,loader需要先下载,再使用(配置loader)
处理html资源时我们需要用到插件(plugins),plugins也是需要先下载,然后是需要引入,其次是使用
处理html资源所用的插件是html-webpack-plugin
npm i html-webpack-liugin -D // 下载创建文件
根目录 ---build ---src ---index.html ---index.js ---webpack.config.js <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Hello html</h1> </body> </html> function add(num,num2) { return num + num2 } console.log(add(3,3)) const { resolve } = reuqire('path') // 下载后,这里引入htnml插件 const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: './src/index.js', output: { filename: 'build.js', path: resolve(__dirname,'build') }, module: { rules: [] }, plugins: [ // html-webpack-plugin // HtmlWebpackPlugin因为它是一个构造函数,使用new 调用 // 功能:默认会创建一个空的HTML,自动引入打包输出的所有资源(js/css) new HtmlWebpackPlugin() ], // 模式 mode: 'development' // 开发模式 // mode: 'production' // 生产 } 这样就简单的配置好了使用webpack命令,就会在build文件夹下多出两个文件,一个build.js和一个index.html,打开index.html文件会发现自动引入了build.js不需要再入上面一样,需要自己创建index.html文件,手动引入build.js
<!-- ./build/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 这就是自动添加的,不是手动添加的 --> <script type="text/javascript" src="build.js"></script> </body> </html>这里会发现src/index.html和build/index.html,除了build下自动引入了build.js,src/index.html的<h1>的内容在build/index.html中不存在 ,但add()方法还是会执行
需求:需要有结构的HTML文件。就是说不只要自动引入build.js。我们编写的html结构也要打包处理出来
plugins: [ new HtmlWebpackPlugin({ // 使用template属性,就会复制'./src/index.html'文件,并自动引入打包输出的所有资源 template: './src/index.html' }) ],这样配置完成后运行webpack命令,在打开build/index.html文件,就会发现有src/index.html的结构了
<!-- ./build/index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Hello html</h1> <!-- 这就是自动添加的,不是手动添加的 --> <script type="text/javascript" src="build.js"></script> </body> </html>这样结构既有了html结构,add()方法也会执行
打包图片资源需要用到两个loader: url-loader, file-loader
// webpack基本配置 const {resolve} = require('path') const HtmlWebpackPlugin = reuqire('html-webpack-plugin') module.exports = { entry: './src/index', output: { fileaname: 'build.js', path: resolve(__dirname, 'build') }, module:{ rules: [ { test: /\.(jpg|png|gif)$/, // 这里只使用一个loader处理时,可以不用使用数组的形式,直接使用laoder:'loader名'的形式 // 这里能因为url-loader是依赖于file-loader的,所以需要下载两个loader loader: 'url-loader', //options是用于对loader进行配置 options: { // 打包图片的时候不会原封不动的输出 // 这个limit配置是:当图片大小 小于 32kb,就会被base64处理 // 优点:减少请求数量(减轻服务器压力) // 缺点: 图片体积会更大(base64)(文件请求变慢) limit: 32 * 1024 } } ] }, plugins: [ new HtmlWebpackPlugin({ template: './src/index.html' }) ], mode: 'development' }
这样就配置好了一个打包图片资源的loader,运行webpack命令后,会在build文件下看到处理后的打包文件,其中图片文件的名称是一串长字符,是hash值
但是这用配置只能处理css中的图片引入(backgroung-img:url(’…’)),对于html文件中的图片引入(img)是处理不了的,只会原封不动的复制过去
// build文件下的html文件 <img src="./01.html"> // 这里 如果说按上述配置了webpack,打包完成后,src就相对路径,这build文件下是找不到为01的图片的。 所以说要处理html文件中的图片引入问题,还需要借助一个loader来处理html-loader
module:{ rules: [ { test: /\.(jpg|png|gif)$/, loader: 'url-loader', options: { limit: 32 * 1024, //关闭url-loader的es6模块化 esModule: false, // 给图片重命名 // [hash:10] 去图片的hash前10位 // [ext] 文件的原扩展名 name: '[hash:10].[ext]' } }, { test: /\.html$/, // 处理html文件中的img图片引入(负责引入这个图片,从而能被url-loader处理) laoder: 'html-loader' } ] }这里运行webpack处理时,还会有一个问题,打包后img图片的src出错了,这是因为url-loader默认使用es6模块解析,而html-loader引入图片是commonjs,解决:关闭url-laoder的es6模块化,使用commonjs
<!--build/index.html--> <img src="[object Moudle]">例如:字体资源,字体图标资源等等
这些资源不需要做其他处理,原封不动输出出去,这些资源就属于其他资源
处理其他资源统一使用file-loader处理
//在入口文件index.js中引入要处理的其他资源 import './index.css' // css中包含了字体资源 // webpack.config.js中的loadere配置 module: { rules: [ { test:/\.css$/, use: ['style-loader', 'css-loader'] }, // 打包其他资源(除了html/css/js资源以为的其他资源) { // 使用exclude排除css/html/js资源 exclude:/\.(html|css|js)$/, loader: 'file-loader' } ] }