npm init -y
得到配置文件package.json用于记录第三方下载的依赖包。然后创建src文件夹,在src文件夹下新建index.html和index.js文件ul>li{这是第 $ 个li}*9
npm install jquery -S
//added 1 package from 1 contributor in 0.824s PS D:\vueProject\webpack>
import $ from 'jquery' //导入jquery
$(function(){
$('li:odd').css('background-color','red')
$('li:even').css('background-color','pink')
})
<script src="./index.js"></script>
//Uncaught SyntaxError: import declarations may only appear at top level of a module
vue工程目录
vue要做的事情很单纯,通过main.js把App.vue的ui结构渲染到index.html的指定区域中。
npm install [email protected] [email protected] -D
//报错就用cnpm
此时package.json里的“devDependencies”节点下多了webpack和webpack-cli的版本号
"devDependencies": {//只是开发阶段使用到 -D
"webpack": "^5.42.1",
"webpack-cli": "^4.7.2"
},
"dependencies":{}//开发阶段和项目上线后都使用到 -S
了解更多请查看官方文档npmjs.com/package/webpack
webpack.config.js
配置文件module.exports={//使用node.js的导出语法,向外导出配置对象
mode:'development',//开发模式 不会压缩代码(注释)
//production 生产模式 会压缩代码(注释)
}
package.json
配置文件的script节点下新增dev脚本, "scripts": {//指定用于对项目打包构建的命令
"dev": "webpack"//script下的脚本可以通过过npm run执行;比如npm run dev
},//运行webpack前会读取webpack.config.js配置文件,拿到文件中向外导出的选项,
在4.x和5.x的版本中,有如下默认约定
src/index.js
dist/main.js
可以在webpack.config.js配置文件中修改打包的默认规定
const path = require('path');//nodejs的核心模块,专门用来处理路径问题的
module.exports={
// 入口路径(相对路径)
entry:path.join(__dirname,'./src/main.js'),//__dirname表示当前文件的存放路径
// 文件输出路径
output:{
//路径
path:path.join(__dirname,'dist'),
//名称
filename:'main.js',
//打包前先清空上次已打包的目录
clean:true,
},
mode:'development',
}
再次npm run dev 就打包好了bundle.js文件了;在index.html页面引入即可解决前面报错问题。
webpack-dev-server插件会监听源代码,当修改了源代码webpack会自动对项目进行打包构建
npm install [email protected] -D
"scripts": {
"dev": "webpack server"//新增了server
},
npm run dev
//如果报错[webpack-cli] Unable to load '@webpack-cli/serve' command
[webpack-cli] TypeError: options.forEach is not a function,就重新安装一下
npm i --save-dev webpack-cli
//如果报错 Error: listen EACCES: permission denied 127.0.0.1:8080
//杀掉8080端口 以管理员身份运行
netstat -ano|findstr "8080" //记住pid 11244
taskkill/pid 11244 -t -f // PID为117884的进程被杀掉
//再次
npm run dev
如果你的根目录没有index.html文件则打开后是这样的
虽然打包生成的main.js却没有出现,但是他是存在的;因为插件打包生成的main.js并没有被存放到实际的物理磁盘上,他是被放到内存中的。http://localhost:8080/main.js即可访问到。因为需要频繁的监听修改和打包,放在内存中效率会比较高。
想办法把src下的index.html页面复制到根目录下,这样就不用手动打开了。看下个插件
该插件可以帮你复制一个新的html页面,并存放到内存中。新旧页面是完全独立的
先安装
npm install [email protected] -D
配置
只需要在webpack.config.js配置文件如此如此即可…
const HtmlPlugin = require('html-webpack-plugin');//导入HTML插件,得到一个构造函数
const htmlPlugin = new HtmlPlugin({//实例化一个html插件对象
template:'./src/index.html',//原文件存放路径
filename:'./index.html'//生成文件路径
})
module.exports={//挂载
plugins:[htmlPlugin],//通过plugins节点,使htmlPlugin插件生效;
}
npm run dev 即可;原理依旧是将其复制一份放到内存中,并不是在物理磁盘上。
webpack默认只能打包js文件,需要打包其他资源时则需要loader;loader的作用主要是协助webpack打包处理特定的文件模块。
首先解决css的打包问题
需要在src目录下新建css文件夹,然后再新建index.css文件;
li{
list-style: none;
}
在index.js中导入css文件;如果你项目没停,那就报错了;不要慌,看下一步。
//导入样式
import './css/index.css'
//报错内容:You may need an appropriate loader to handle this file type
安装style-loader和css-loader
npm i [email protected] [email protected]
在webpack.config.js配置文件里的module节点下进行配置
module.exports={
module:{//所有第三方文件模块的匹配规则
rules:[//$代表以.css结尾
{test:/\.css$/,use:['style-loader','css-loader']}
]
}
}
//这里有个坑,loader调用的时候是从后往前调的,use:['style-loader','css-loader']顺序不能反
简单梳理这个css文件的处理过程:
为方便演示,现在css文件夹下创建index.less文件
html,body,ul{
margin:0;
padding:0;
li{
line-height: 30px;
padding: 20px;
font-size: 12px;
}
}
跟之前一样,在index.js里import一下
import './css/index.less';
//不出意外,如果你项目没停,又报错了;不要慌,下一步
//报错内容:You may need an appropriate loader to handle this file type
下载less-loader
npm i [email protected] [email protected] -D
//less只是内置依赖项,配置时只需配置style-loader,css-loader,less-loader
配置
module:{//所有第三方文件模块的匹配规则
rules:[//$代表以.css结尾
{test:/\.css$/,use:['style-loader','css-loader']},
{test:/\.less/,use:['style-loader','css-loader','less-loader']}
]
},
npm run dev 即可
base64是怎么回事?
现在与src平级目录下新建一个test文件夹,导入一张图片并创建一个html页面,并将图片显示。然后通过工具转化成base64格式的字符串:
//太基尔长了,这里省略
data:image/jpeg;base64,/9j/4AAQSkZJR......
使用base64的优缺点:
现在开始演示怎么打包图片了
先在src文件夹中新建img文件夹,并将图片引入到index.html中
在index.js文件里import图片的路径
import logo from './img/1.jpg';
然后再给img标签的src动态赋值
$('.box').attr('src',logo);
然后又又又爆错了
//You may need an appropriate loader to handle this file type
//不要慌
//打包处理样式表中与路径相关的文件
npm i [email protected] [email protected] -D
module:{//所有第三方文件模块的匹配规则
rules:[
//?后面是loader的参数项,只有<=limit大小的图片才会转为base64格式。单位是子节
{test:/\.jpg|png|jpeg|gif$/,use:'url-loader?limit=22229'}
]
},
npm run dev
//这样打包之后,jpg格式的就变成了base64格式了
webpack只能打包部分高级js语法,对于那些webpack无法处理的高级js语法,需要借助于bable-loader进行打包处理。
举个栗子:在index.js里定义一个修饰器函数指向一个Person类
//定义一个修饰器函数
function info(target){
target.info = 'Person info'
}
//定义一个Person类
@info
class Person{}
console.log(Person.info);//不出意外,绝对报错了
/ERROR in ./src/index.js 20:0
Module parse failed: Unexpected character '@'
(20:0)
You may need an appropriate loader to handle this file type, /
npm i [email protected] @babel/[email protected] @babel/[email protected] -D
//最后那个包是转换修饰器函数语法的
module:{//所有第三方文件模块的匹配规则
rules:[
{test:/\.js$/,use:'babel-loader',exclude:/node_modules/}
//排除/node_modules里的代码,这是第三方包
]
},
在项目根目录下创建名为babel.config.js的配置文件,定义Babel的配置项:
查看官网:babeljs.io/docs/en/babel-plugin-proposal-decorators
module.exports={
// 声明babel可用的插件
//webpack在调用babel-loader的时候,会先加载plugins插件来使用(就是插件里的插件)
plugins:[['@babel/plugin-proposal-decorators',{legacy:true}]]
}
npm run dev
//完事
首先在package.json文件的script节点下新增build命令:
"scripts": {
"dev": "webpack server",//自动实时打包(放在内存)
"build":"webpack --mode production"//项目发布时,运行built命令
},
js文件路径:在webpack.config.js中设置
module.exports={
// 入口路径(相对路径)
entry:path.join(__dirname,'./src/index.js'),//__dirname表示当前文件的存放路径
// 文件输出路径
output:{
//路径
path:path.join(__dirname,'dist'),
//名称
filename:'js/bundle.js',
//打包前先清空上次已打包的目录
clean:true,
},
}
图片路径:
module.exports={
module:{//所有第三方文件模块的匹配规则
rules:[
{test:/\.jpg|png|jpeg|gif$/,use:'url-loader?limit=22229&outputPath=images'},
]
},
}
官网:https://www.npmjs.com/package/clean-webpack-plugin
这个插件就是打包时自动删除上次打包的内容
安装
npm i -D clean-webpack-plugin
在webpack.config.js配置文件里进行配置
// 导入clean-webpack-plugin插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');//解构赋值的语法
//注入插件使用
plugins:[htmlPlugin, new CleanWebpackPlugin()],//通过plugins节点,使Plugin插件生效
npm run build完事
打包的总结:
Source Map是一个信息文件,存储位置信息。Source Map 文件中存储着压缩混淆后的代码,所对应的转换前的位置。
通过Source Map可以找到源代码。
在开发环境下默认生成的Source Map,记录的是生成后(打包后)代码的位置,导致运行时报错的行数,与源代码的行数不一致。
举个栗子:
故意在index.js文件里写入一句错误的代码(记住这一行号23)
23 consle.log(123);
npm run dev 然后 f12。发现提示报错的行号不对。到这里你懂就行
32 consle.log(123);
module.exports={
mode:'development',
devtool:'eval-source-map',
}
//配置后发现报错行号是对的
在项目发布时应该关闭Source Map,防止源码暴露
只定位行数,不暴露源码
module.exports={
mode:'development',
devtool:'nosources-source-map',
}
建议在开发环境时使用eval-source-map
;发布时使用nosources-source-map
或者不使用source-map
在webpack.config.js中配置:
module:{},
resolve:{
alias:{//@表示src这层目录
'@':path.join(__diename,'./src')
}
},