现阶段前端打包工具很多,目前常用的是webpack,grunt等,在没出现更好的工具之前,学好这两个其中的一个基本都够用了,目前最流行的还属webpack,也是很多面试官喜欢问的话题,这篇文章从零了解打包机制,只要你有耐心保证你会有收获。
安装webpack和webpack-cli依赖
首先,还是需要初始化项目(npm init),这里安装的依赖建议是本地依赖而不是全局依赖,如果安装本地依赖又安装全局依赖容易把人搞混,但是本地依赖不能使用webpack命令,只能根据配置项来执行。(npm install --save-dev webpack webpack-cli)
配置package.json打包项
{
......
"scripts": {
"build": "webpack --config webpack.prod.js"
}
......
}
新建webpack.prod.js文件并进行配置
在当前目录建立index.html,在src目录下建立main.js,这里的webpack配置运行的环境是node,我们就可以使用common规范进行编码,entry(打包入口)output(打包出口,配置打包出口路径和名字)。这里使用了path.resolve进行凭借,原因是window和linus解析路径"/"不一样,这里做兼容处理。
const path = require("path");
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
}
};
配置html-webpack-plugin插件自动生成index.html
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html'
})
]
};
配置clean-webpack-plugin打包前先清除原有文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin()
]
};
在main.js配置vue3入口
这里使用的是vue3语法,还需要引用vue(npm install --save-dev vue)
import {createApp} from 'vue';
import App from './App.vue';
createApp(App).mount("#app");
在src目录下建立App.vue根组件
树木图片-{{prive}}
使用vue-loader编译vue文件
下载依赖(npm install --save-dev vue-loader)
const { VueLoaderPlugin } = require('vue-loader');
module.exports = {
module: {
rules: [
{ test: /\.vue$/, use: 'vue-loader' }
]
},
plugins: [
new VueLoaderPlugin()
]
};
使用babel-loader编译js文件
下载依赖(npm install --save-dev babel-loader @babel/core @babel/preset-env)
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [{
loader: "babel-loader",
options: {
presets: ["@babel/env"]
}
}]
}
]
}
};
使用ts-loader编译ts文件
在项目根路径创建tsconfig.json文件,下载依赖(npm install --save-dev ts-loader)
module.exports = {
module: {
rules: [
{ test: /\.ts$/, use: 'ts-loader' }
]
}
};
使用css-loader编译css文件
这里use依赖是从后往前执行,顺序不能反,先嵌入css文件在把css文件加载到style标签中,下载依赖(npm install --save-dev style-loader css-loader)
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};
使用url-loader编译image文件
下载依赖(npm install --save-dev url-loader file-loader)
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|jpeg|gif|svg)/,
use: {
loader: 'url-loader',
options: {
outputPath: 'static/',
limit: 10 * 1024
}
}
}
]
}
};
区分打包环境
项目根目录创建webpack.common.js、webpack.prod.js、webpack.dev.js三个文件,通过webpack-merge提取出公用配置(npm install --save-dev webpack-merge)。注意:devtool配置会新建map文件,作用是打包后的文件和开发文件建立映射关系,方便定位问题。
webpack.prod.js
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.common.js");
module.exports = merge(commonConfig,{
mode: 'production'
});
webpack.dev.js
const path = require("path");
const { merge } = require("webpack-merge");
const commonConfig = require("./webpack.common.js");
const devConfig = {
mode:'development',
devtool:'cheap-module-source-map',
//webpack-dev-server配置本地服务器,并配置跨域
devServer:{
static: path.join(__dirname, "dist"),
port: 8000, // 本地服务器端口号
hot: true, // 热重载
proxy: {
'/api/*': {
target: 'http://localhost:3333', // 目标服务器地址
secure: false, // 目标服务器地址是否是安全协议
changeOrigin: true, // 是否修改来源, 为true时会让目标服务器以为是webpack-dev-server发出的请求!
}
}
}
}
module.exports = merge(commonConfig,devConfig);
使用cross-env区分打包环境
下载依赖(npm install --save-dev cross-env)
{
"scripts": {
"start": "webpack-dev-server --config webpack.dev.js",
"dev": "cross-env NODE_ENV=development webpack --config webpack.dev.js",
"build": "cross-env NODE_ENV=production webpack --config webpack.prod.js"
}
封装axios区分服务
项目根目录建config目录建立server.ts封装公用的axios调用接口,通过process.env.NODE_ENV区分使用的服务。
import axios from 'axios';
let baseUrl:string = ""
if(process.env.NODE_ENV == "development"){
baseUrl = "http://development.com"
}else if(process.env.NODE_ENV == "production"){
baseUrl = "http://production.com"
}
console.log(baseUrl)
const server = axios.create({
baseURL: baseUrl,
timeout: 10000
})
server.interceptors.request.use(config => {
console.log("请求拦截");
return config;
})
server.interceptors.response.use(response => {
console.log("响应拦截");
return response.data;
})
export default server;