webpack笔记
目录
简介
是一个前端项目的构建工具,可以实现资源的合并、打包、压缩、混淆等功能,是基于nodejs开发的;
官方文档:https://webpack.js.org/
官方中文文档:https://www.webpackjs.com/
安装使用
安装:
- 项目安装(推荐):
npm install webpack webpack-cli --save-dev
; - 全局安装:
npm install webpack webpack-cli --global
;
使用(打包js文件):
- 创建目录,接着执行:
npm init -y
; - 创建
src
源码目录,并在该目录下创建index.js
和index.html
文件; - 根目录下创建
webpack.config.js
文件(参见示例配置); package.json
的scripts
下添加"build": "webpack"
;- 打包时指定配置文件:
"build": "webpack --config webpack.prod.config.js"
- 执行打包命令:
npm run build
(会将js文件打包到dist文件夹); - 访问
index.html
页面查看效果。
热打包
在上面的基础上再进行如下操作:
- 安装webpack-dev-server:
npm install webpack-dev-server --save-dev
; package.json
的scripts
下添加"start": "webpack-dev-server --port 8080"
;- 执行命令:
npm run start
(会开启web服务器,并在内存中将js文件热打包到根目录下); - 浏览器访问:
localhost:8080/
查看效果;
html文件的打包与热加载(基于上面的步骤):
- 安装:
npm install html-webpack-plugin --save-dev
; webpack.config.js
添加该插件相关配置(见示例配置);- 打包:
npm run build
(会一并打包html,并自动添加js的依赖); - 执行命令:
npm run start
(会一并热部署html); - 浏览器访问:
localhost:8080/
;
css-loader
webpack默认只能打包js类型的文件,要处理非js文件,需要安装一些合适的第三方加载器loader
,这里要处理css文件的方法如下:
- 安装loader:
npm i style-loader css-loader -D
- 在
webpack.config.js
添加配置:
// 配置加载器loader
module: {
rules: [
// css加载器,且启用css模块化
{test: /\.css$/, use: ['style-loader', {loader: 'css-loader', options: {modules: true}}]}
]
}
- 在js代码中导入(局部):
import a from './css/index.css'
- 全局css:将css文件中的选择器用
:global()
括起来
另外:也可以在webpack.config.js
使用如下配置:
module: {
rules: [
{test: /\.css$/, use: ['style-loader', 'css-loader'], exclude: /\.m\.css/},
{test: /\.m\.css$/, use: ['style-loader', {loader: 'css-loader', options: {modules: true}}]}
]
}
这样就可以根据导入的文件的后缀名确定是全局应用还是局部引用。
url-loader
由于webpack的特性,当在css文件中引用图片时,则会打包失败,故引入url-loader;使用步骤如下:
- 安装:
npm i url-loader file-loader -D
; - 配置:
{test: /\.(jpg|gif|png|jpeg|bmp)$/, use: 'url-loader?limit=10240&name=[hash:8]/[name].[ext]'}
- 使用:
import imgUrl from './img/1.jpg'
或在css
文件中:url('./img/2.jpg')
- url-loader也可以处理字体:
{test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader'}
JSX支持(需要react)
概念:js文件中默认不能写html标语语言,但是可以使用babel来转换为react的创建语句,这种在JS中混合写入HTML,符合xml规范的语法,叫做JSX语法,而webpack只支持原生js语法,所以需要在webpack中添加加载器loader,步骤如下:
使用babel-loader预编译jsx
语法:
使用文档:https://www.npmjs.com/package/babel-loader
- 安装babel以及相关依赖:
npm i babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/preset-react -D
- 依赖模块作用说明:
@babel/preset-env
:编译ES6@babel/preset-react
:转化JSX@babel/plugin-transform-runtime
:避免polyfill
污染全局变量,减小打包体积
- 在
webpack.config.js
文件中添加如下配置:
module: {
rules: [
// node_modules该目录下的文件不使用第三方插件打包
{
test: /(\.js|\.jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options:{
presets: [
'@babel/preset-env',
'@babel/preset-react'],
plugins: ['@babel/transform-runtime']
}
}
}
]
}
- 接着就可以在js文件中使用如下方式创建元素了
const div = <div id="div">这是一个div</div>
vue支持
网页版vue(不推荐)
使用网页版的vue(不推荐)
- 安装vue:
npm i vue -S
- 安装vue-router:
npm install vue-router -S
- 在
webpack.config.js
文件中添加如下配置
resolve: {
// 给网页版vue取别名,然后就可以在js中使用该别名导入网页版vue
alias: {
vue$: 'vue/dist/vue.js'
}
},
- 接着就可以通过:
import Vue from 'vue'
导入使用vue了
vue-loader
文档:
https://vue-loader.vuejs.org/zh/
使用步骤:
- 安装:
npm i vue-loader vue-template-compiler -D
- 配置1:
const VueLoaderPlugin = require('vue-loader/lib/plugin')
- 配置2:
plugins: [new VueLoaderPlugin()],
- 配置3:
{test: /\.vue$/, use: 'vue-loader'}
vue脚手架
详情参见:
https://cn.vuejs.org/v2/guide/installation.html
示例配置
package.json
{
"name": "ms_demo",
"version": "1.0.0",
"description": "ms_demo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --port 8080",
"build": "webpack --config webpack.config.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^5.0.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^4.5.0",
"style-loader": "^2.0.0",
"url-loader": "^4.1.1",
"vue-loader": "^15.9.4",
"vue-template-compiler": "^2.6.12",
"webpack": "^5.3.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"axios": "^0.21.0",
"jquery": "^3.5.1",
"qs": "^6.9.4",
"sweetalert": "^2.1.2",
"vue": "^2.6.12",
"vue-router": "^3.4.8"
}
}
webpack.config.js
const path = require('path')
// html热打包插件
const HtmlWebPackPlugin = require('html-webpack-plugin')
// vue-loader
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack')
module.exports = {
entry: './src/index.js',
mode: 'development',//production
plugins: [
// 打包的html会自动在底部加上对热打包的js文件的依赖
new HtmlWebPackPlugin({
template: path.join(__dirname, './public/index.html'), // 源文件
filename: 'index.html' // 生成在内存中首页的名称
}),
new VueLoaderPlugin(), //vue-loader
new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }),
// 在编译时预先自定义的全局变量
new webpack.DefinePlugin({ frontUrlPrefix: JSON.stringify('/'), axiosBaseURL: JSON.stringify('/main') })
],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/', //打包后的访问路径前缀
},
module: {
rules: [
// 加载器
{ test: /\.css$/, use: ['style-loader', { loader: 'css-loader', options: { modules: false } }] },
{ test: /\.(jpg|gif|png|jpeg|bmp)$/, use: 'url-loader?limit=10240&name=[hash:8]/[name].[ext]' },
{ test: /\.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader' },
{ test: /\.vue$/, use: 'vue-loader' }
]
},
resolve: {
extensions: ['.js', '.vue', '.css'],
alias: {
// 使用绝对路径
'@': path.resolve(__dirname, './'),
}
},
// 代理的后端地址
devServer: {
proxy: {
'/main': {
target: 'http://localhost:81/',
pathRewrite: { '^/main': '/main' }
}
},
disableHostCheck: true
}
}