parcel开发第三方包的时候用的比较多,webpack做项目的时候用的比较多
遇到的问题:ES6导入语法import在浏览器中报错,不兼容ES6
npm init -y
npm i jquery -S
疑问:这里js文件要在src下,不能在src的js下,否则报错,why
解决: 因为webpack默认的入口是src/index.js文件 所以要改的话,得进行配置,后面会涉及到怎么配置。
在终端运行如下的命令,安装webpack 相关的两个包:
npm i webpack webpack-cli -D
-S = --save 开发和部署后都需要依赖的包
-D = --save-dev 只有开发的时候依赖的包
具体使用哪个可以去npmjs.com去搜
1.在项目根目录中,创建名为webpack.config.js的webpack配置文件,并初始化如下的基本配置:
//使用 node.js 中的导出语法,向外导出一个 webpack 的配置对象
module.exports = {
//mode用来指定构建模式,可选 development 和 production
mode: 'development'
}
2.在package.json的scripts节点下,新增dev脚本如下:
"scripts": {
"dev": "webpack"
},
script 节点下的脚本,可以通过 npm run 执行,例如 npm run dev
3.在终端中运行npm run dev命令,启动webpack进行项目的打包构建:
npm run dev
webpack.config.js是 webpack的配置文件。
webpack在真正开始打包构建之前,会先读取这个配置文件,从而基于给定的配置,对项目进行打包。
注意:由于webpack是基于node.js 开发出来的打包工具,因此在它的配置文件中,支持使用node.js 相关的语法和模块进行webpack的个性化配置。
在webpack 4.x和5.x的版本中,有如下的默认约定:
默认的打包入口文件为src -> index.js
默认的输出文件路径为dist -> main.js
注意:可以在webpack.config.js中修改打包的默认约定
在webpack.config.js配置文件中,通过entry节点指定打包的入口。通过output节点指定打包的出口。示例代码如下:
//path是node.js中的一个模块
const path = require('path');
//使用 node.js 中的导出语法,向外导出一个 webpack 的配置对象
module.exports = {
//mode用来指定构建模式,可选 development 和 production
mode: 'development',
//指定要处理的文件,这里__dirname到根目录了,code下,src上
entry: path.join(__dirname,'./src/js/index.js'),
//指定生成的文件要存放的位置及文件名
output: {
//存放到目录
path: path.join(__dirname,'dist'),
//生成的文件名
filename: 'mymian.js'
}
}
通过安装和配置第三方的插件,可以拓展webpack的能力,从而让webpack用起来更方便。最常用的webpack插件有如下两个:
1.webpack-dev-server
类似于node.js 阶段用到的nodemon工具
每当修改了源代码,webpack会自动进行项目的打包和构建
2.html-webpack-plugin
webpack中的HTML插件(类似于一个模板引擎插件)
可以通过此插件自定制index.html页面的内容
运行如下的命令,即可在项目中安装此插件:
npm install webpack-dev-server -D
配置:
1.修改package.json -> scripts中的dev命令如下:
"scripts": {
"dev": "webpack-dev-server"
},
2.在webpack.config.js配置
const path = require('path');
module.exports = {
//mode用来指定构建模式,可选 development 和 production
mode: 'development',
devServer: {
static: { //4版本之后不再是contentBase
directory: __dirname,//指定托管的根目录为根目录
},
compress: true,
port: 9000,
open: true,//自动打开浏览器
hot: true//启用热更新
},
}
<script src="../dist/main.js" type="text/javascript" charset="utf-8"></script>
这里用的就是生成的js,webpack会在内存中存一份这个放到根目录, 后面用上第二个插件,就不需要我们引用了,插件会帮我们去引用
4.再次运行npm run dev命令,重新进行项目的打包
5.在浏览器中访问http://localhost:9000地址,查看自动打包效果
注意:webpack-dev-server会启动一个实时打包的http服务器
运行如下的命令,即可在项目中安装此插件:
npm install html-webpack-plugin -D
配置:
//1.导入 HTML 插件,得到一个构造函数
const HtmlPlugin = require('html-webpack-plugin')
//2.创建 HTML 插件的实例对象
const htmlPlugin = new HtmlPlugin({
template: './src/index.html',//指定原文件的存放路径
filename: './index.html' //指定生成的文件的存放路径
})
//使用 node.js 中的导出语法,向外导出一个 webpack 的配置对象
module.exports = {
//3.mode用来指定构建模式,可选 development 和 production
mode: 'development',
plugins: [htmlPlugin] //通过 plugins 节点,使 htmlPlugin 插件生效
}
html-webpack-plugin这个插件还有个作用,就是可以自动给我们把内存中的生成的index.js文件注入到index.html中,不需要我们手动引入了
就是会在head中自动给添加这么一句话,把内存中的mian.js给调用出来了
<script defer="" src="main.js">script>
在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块,webpack 默认处理不了,需要调用 loader 加载器才可以正常打包,否则会报错!
loader加载器的作用:协助 webpack 打包处理特定的文件模块。比如:
1.安装
npm i style-loader css-loader -D
2.在webpack.config.js文件中添加loader规则
module: {
rules: [
//定义了不同模块对应的loader
{
test: /\.css$/,use: ['style-loader','css-loader']
}
]
}
现在,在js文件中,就可以调用 css 文件了
//1.使用ES6导入语法导入jQuery
import $ from "jquery"
import '../css/index.css'
$(function(){
//2.实现隔行变色
$('li:odd').css('background-color','green');
$('li:even').css('background-color','red');
}
)
注意:我这里使用…/是因为我的js文件在js文件夹下,所以需要往上跳一层,才能调用到css文件夹
1.安装
npm i less-loader less -D
2.配置
module: {
rules: [
//定义了不同模块对应的loader
{
test: /\.css$/,use: ['style-loader','css-loader']
},
{
test: /\.less$/,use: ['style-loader','css-loader','less-loader']
}
]
}
1.安装
npm i url-loader file-loader -D
2.配置
module: {
rules: [
//定义了不同模块对应的loader
{
test: /\.css$/,use: ['style-loader','css-loader']
},
{
test: /\.less$/,use: ['style-loader','css-loader','less-loader']
},
{
test: /\.jpg|png|gif$/,use: ['url-loader?limit=20000']
}
]
}
webpack只能打包处理一部分高级的JavaScript 语法。对于那些webpack 无法处理的高级js语法,需要借助于babel-loader进行打包处理。例如webpack无法处理下面的JavaScript代码:
//定义装饰器函数
function info(target){
target.info = 'person info';
}
//定义一个普通的类
@info
class Person{}
console.log(Person.info)
1.安装
npm i babel-loader @babel/core @babel/plugin-proposal-decorators -D
2.配置
module: {
rules: [
//定义了不同模块对应的loader
{
test: /\.css$/,use: ['style-loader','css-loader']
},
{
test: /\.less$/,use: ['style-loader','css-loader','less-loader']
},
{
test: /\.jpg|png|gif$/,use: ['url-loader?limit=20000']
},
{
test: /\.js$/,use: ['babel-loader'],exclude: /node_modules/
}
]
}
在配置 babel-loader 的时候,程序员只需要把自己的代码进行转换即可,一定要排除 node_modules 目录中的JS 文件
然后在项目根目录下,创建名为babel.config.js的配置文件,定义Babel的配置项如下:
module.exports = {
//声明 babel 可用的插件, webpack 在调用 babel-loader 的时候 ,会先加载下面的插件
plugins: [
['@babel/plugin-proposal-decorators',{legacy: true}]
]
}
实际使用什么插件,去babel官网去找就可以了,找到后添加到plugins数组中就可以了
https://babeljs.io/docs/en/babel-plugin-proposal-decorators
因为使用了devserver,所以生成的js文件在内存中,并没有在dist中生成文件
配置了devserver,自定义的入口依旧生效,但出口不生效了
所以需要用build打包一下
在package.json文件的scripts节点下,新增build命令如下:
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack --mode production"
},
--model是一个参数项,用来指定webpack 的运行模式。production代表生产环境,会对打包生成的文件进行代码压缩和性能优化。
注意:通过–model指定的参数项,会覆盖webpack.config.js 中的 model选项。
配置webpack的模式默认就是开发环境,打包的时候在打包命令上给他切换为生产环境
output: {
//存放到目录
path: path.join(__dirname,'dist'),
//生成的文件名
filename: 'js/main.js'
},
{
test: /\.jpg|png|gif$/,use: ['url-loader?limit=20000&outputPath=images']
}
https://www.npmjs.com/package/clean-webpack-plugin
**SourceMap 就是一个信息文件,里面储存着位置信息。**也就是说,SourceMap 文件中存储着压缩混淆后的代码,所对应的转换前的位置。
有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,能够极大的方便后期的调试。
这个东西记录在main.js.map文件中
开发环境下,推荐在webpack.config.js中添加如下的配置,即可保证运行时报错的行数与源代码的行数保持一致:
module.exports = {
//mode用来指定构建模式,可选 development 和 production
mode: 'development',
//运行时行号和源代码行号保持一致
devtool: 'eval-source-map',
}
可以删掉,大家都看不到
或者改成另一个属性,显示行号,但是不能链接到源码,这样,自己可以根据行号去看自己哪里错了
此时只需要将 devtool 属性设置为 nosources-source-map
发布时最好是删除了 devtool 属性
警告:千万不要将 devtool 属性设置为 source-map ,这样的话,发布之后依然可以定位到源码
@在webpack中不能直接使用,需要配置别名才可以使用
@/是从外往里找 ./是从里往外找 这样如果文件特别深,需要很多…/
resolve: {
alias: {
//告诉webpack @表示src这一层目录
'@': path.join(__dirname,'./src/')
}
}
import '@/css/index.css'
import '../css/index.less'
这样就看出区别来了吧,使用 @ 就不需要考虑他到底是在那一层,只要是在 @ 所关联的 src 层下就行