webpack是什么?webpack是一个打包工具。当前环境下模块化开发的趋势非常盛行。主要有Common.js和module。但浏览器并不能运行我们直接运行各项目包之间的关系。即使将他们放置在一个入口文件中,那么webpack的目的就是将这些包的之间的依赖关系处理成我们浏览器中所能运行的js代码。打包并不是单纯的代码打包,还是整体过程的一个优化。
典型例子:vue中为什么可以使用import 导入 react中为啥可以使用module
安装一下webpack webpack-cli 建议局部安装,如果团队里面webpack版本不一样,会造成打包的代码不一样,协作会出问题
先来看一个简单的例子
index.html
Document
A.js
function printA() {console.log('A');
}
export default printA
B.js
function printB() {console.log("B");
}
export default printA
index.js
import A from './A/A'
import B from './B/B'
如果不使用webpack打包的话,会报错===Uncaught SyntaxError: Cannot use import statement outside a module
如果我们引入打包后的文件 ,将不会报错。
默认情况下,webpack入口文件是src/index.js 输出文件是 dist/main.js
修改出口,入口等配置信息。我们有两种信息,
第一种是通过命令来修改
webpack --entry ./src/app.js
这个入口文件就是src下面的app.js
第二种是通过webpack配置文件
默认情况下,webpack在执行的时候会自动地去寻找看是否有webpack.config.js这个配置文件。如何修改呢?
也是在命令的时候修改
webpack.config.js
const path = require('path')
module.exports = {//入口文件entry: './src/index.js',output: {//文件名filename: 'index.js',//文件夹path: path.join(__dirname, './build')//path配置项需要绝对路径}
}
webpack --config 配置文件名字
我们打包的时候,如果有==css文件,需要进行配置==,webpack才能正常进行打包。一般,配置这些资源处理模块的,都放在module配置项当中—module!要处理css,需要安装css-loader,style-loader:前者是处理css各模块之间的依赖关系(处理import和require之间的关系) 后者是将处理的css文件放在页面当中。来看一个例子
const path = require('path')
module.exports = {entry: './index.js',output: {filename: 'index.js',path: path.join(__dirname, './build')},module: {rules: [//css{test: /\.css$/,use: ['style-loader', 'css-loader']},//less{test: /\.less$/,use: ['style-loader', 'css-loader', 'less-loader']},//静态资源处理{test: /\.(jpg|png|webp)$/,type: 'asset/resource'//这个是内置包}]}
}
webpack给我们提供了一个变量
[name] 之前文件名
[ext] 之前后缀名
[hash:] 表示生成number位的hash值
在module/rules/generator里面配置打包后的名字🥰
const path = require('path')module.exports = {entry: './index.js',output: {filename: 'index.js',//文件夹名必须是绝对路径path: path.join(__dirname, './build')},module: {rules: [{test: /\.css/,use: ["style-loader", "css-loader"]},{test: /\.png/i,type: 'asset/resource',generator: {filename: "[name][ext]"}}]}
}
但这样的方法,难免会有命名重复的图片,这个时候,在打包的时候,会产生分歧,此时我们就要用添加hash值来命名图片名称。
const path = require('path')module.exports = {entry: './index.js',output: {filename: 'index.js',//文件夹名必须是绝对路径path: path.join(__dirname, './build'),clean: true},module: {rules: [{test: /\.css/,use: ["style-loader", "css-loader"]},{test: /\.png/i,type: 'asset/resource',generator: {filename: "[name].[hash:6][ext]"}}]}
}
这种生成静态文件的命名方式也是Vue中打包的形式。
对于小型图片,我们可以打包成base64格式的图片。base64的原理就是将图片的各个像素点生成出来! 这样,可以减少网络请求。大型图片不建议生成base64的格式,因为这样,base64文件非常大,导致页面代码会非常冗杂。
base64格式
{test: /\.png/i,type: 'asset/inline'}
大图片采用拷贝的方式,小图片采用base64的方式。
const path = require('path')module.exports = {entry: './index.js',output: {filename: 'index.js',//文件夹名必须是绝对路径path: path.join(__dirname, './build'),clean: true},module: {rules: [{test: /\.css/,use: ["style-loader", "css-loader"]},{test: /\.png/i,type: 'asset',generator: {filename: '[name].[hash][ext]'},//设置成base64的最大值parser: {dataUrlCondition: {maxSize: 10 * 1024}}}]}
}
在webpack5之前,通过clean-webpack-plugin来清理
const { CleanWebpackPlugin } = require('clean-webpack-plugin')plugins: [new CleanWebpackPlugin()]
在webpack5,我们可以通过output里面的配置:
output:{clean: true
}
插件 —html-webpack-plugin
const HtmlWebPackPlugin=require(html-webpack-plugin)
plugins:[new HtmlWebpackPlugin()
]
一个重要项:template 让webpack生成的html文件在这个文件上进行添加生成。
利用webpack自带的watch参数,写一个脚本来运行这个watch。在package.json里面配置
scirpts:
“watch”:“webpack --watch”
能够追溯到报错信息具体在哪里
devtool:'inline-source-map'
先下载 webpack-dev-server
在配置选项里面配置:
开启服务,入口文件
devServer:{static:'./dist'
}
然后通过webpack server来启动这个服务,不会产生生成的静态文件夹,文件通过内存来加载(不是通过磁盘),实现实时更新。–open自动打开页面
局部刷新—加快效率以及速度
devServer:{static:'./dist',hot:true
}
然后在入口文件里面配置 通过module.hot
if (module.hot) {module.hot.accept(['./public/input/1'])
}
browserslist是浏览器的配置选项,主要用来搭配一些兼容性的问题!在package.json里面配置。
通过npx browserslist可以查看浏览器。
常见配置项(兼容性):
配置多少版本的浏览器,筛选哪部分的浏览器
插件postcss-loader
还是放在**use**里面,采用==对象==写法:
use:[{loader:'',options:{postcssOptions:{plugins:[require(插件)]}}}
]
目前:我们在项目中所要使用的基本配置已经完成了
webpack.config.js
const path = require('path')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {mode: 'development',entry: "./src/index.js",output: {filename: "js/index.js",path: path.resolve(__dirname, "./dist")},module: {rules: [//css{test: /\.css$/i, //正则use: ['style-loader',{loader: 'css-loader',options: {importLoaders: 1 //css文件遇到了import先交给前一步处理}},/** 需要安装基于postcss-loader的插件** autoprefixer* */'postcss-loader']},//less{test: /\.less$/i,use: ['style-loader',{loader: 'css-loader',options: {importLoaders: 1}},'postcss-loader','less-loader']}]},//插件plugins: [//打包时自动清理上次的打包文件夹new CleanWebpackPlugin(),new HtmlWebpackPlugin({//标题title: "Hello Webpack!",//模板template: "./public/index.html"})]
}
postcss.js
module.exports = {plugins: [require("postcss-preset-env")]
}
babel-loader 需要结合整合包进行操作
@babel/preset-env
webpack的配置项
处理原生api的转换
将模板中的静态资源直接复制到dist目录下
ts-loader typescript
ts工作原理:先将ts转成js,只要js配置好了,就没问题(在解析原生api,高版本js的情况)
ts语法错误情况下还生成dist目录。解决办法:
tsc && webpack
等tsc执行完成后,再执行webpack
首先安装vue–支持vue,vue@next—表示vue的最新版本
vue-loader 加载vue的文件
@vue/compilier-sfc 解析vue的文件
代理本质:通过node创建一个服务器,向后端发送数据请求,服务端与服务端之间不存在跨域!
devServer:{proxy:{'/':'http://localhost:3000'//表示当前所有跟路经情况都向3000端口发送请求。}
}
有时候,不需要所有路径都发送
proxy:{"/api":{target:"http://localhost:3000"pathRewrite:{"^/api",""}}
}
development production 有时候,我们有些配置是要在开发环境下用到的,但在生产环境不需要的。
一般是
在打包生成文件夹的时候,会指定为生产环境。
package.json/scripts
"build":"webpack --env production"
"server":"webpack server --env development"
webpack.config.js配置
const path = require("path")
const {CleanWebpackPlugin} = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const CopyWebpackPlugin = require("copy-webpack-plugin")
const {VueLoaderPlugin} = require("vue-loader")const config = {entry: "./src/index.js",output: {filename: "js/index.js",path: path.resolve(__dirname, "./dist")},plugins: [new CleanWebpackPlugin(),new HtmlWebpackPlugin({title: "Hello Webpack!",template: "./public/index.html"}),new CopyWebpackPlugin({patterns: [{from: "./public",//排除 index.htmlglobOptions: {ignore: ["**/index.html"]}}]}),new VueLoaderPlugin()],module: {rules: [//css{test: /\.css$/i,use: ["style-loader",{loader: "css-loader",options: {importLoaders: 1}},"postcss-loader"]},//less{test: /\.less$/i,use: ["style-loader","css-loader","postcss-loader","less-loader"]},//图片{test: /\.(jpg|png|jpeg|gif|webp)$/i,type: 'asset/resource',generator: {filename: 'images/[name].[hash:8][ext]'}},//字体{test: /\.(ttf|woff2?)$/i,type: 'asset/resource',generator: {filename: 'font/[name].[hash:4][ext]'}},//视频/音频{test: /\.(mp3|mp4|ogg|avi)$/i,type: 'asset/resource',generator: {filename: 'media/[name].[hash:4][ext]'}},//js -- 利用babel-loader{test: /\.js$/i,use: ["babel-loader"]},//vue{test: /\.vue$/i,use: ['vue-loader']}]}
}module.exports = (env)=>{if (env.development){config.mode = "development"config.devServer = {proxy: {/*"/user": "http://localhost:3000","/admin": "http://localhost:3000"*/"/": "http://localhost:3000"/*"/proxy": {target: "http://localhost:3000",pathRewrite: {"^/proxy": ""}}*/}}config.devtool = "source-map"}else{config.mode = "production"}return config
}