前言
本文出自一名菜鸟实习生,最近在公司闲来无事,毫无学习方向,因leader灵魂一问:你是不是还不懂项目为什么需要打包,固花费两天时间把webpack知识深入研究,并且写下本文方便日后查看!注:学习不能单纯复制文章内容,需要一步一步理解!(代码优化部分还没有完全掌握,有时间再来研究)
webpack详细配置
初始化项目
npm init //一路默认回车,生成package.json文件
注:package.json文件是npm的说明文件,管理模块的依赖关系
初始化目录
build文件夹--构建服务和webpack配置
-
build.js:webpack打包服务
-
config.js:该文件主要用于配置构建开发环境和生产环境差异化的参数
-
webpackBase.js:此文件主要用于配置构建开发环境和生成环境的通用配置
-
webpackDev.js:该文件主要用于配置构建开发环境
-
webpackPro.js:该文件主要用于配置构建生产环境
src文件夹--项目目录
- index
- index.js:项目构建入口文件
- index.html:项目入口文件
- index.scss:样式文件
- index.vue:vue文件
/*index.html*/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="index"></div>
</body>
</html>
/*index.js*/
import Vue from "vue";
import index from './index.vue'
import "./index.scss"
function f() {
var aa=3
console.log(111)
console.log(aa)
}
f()
new Vue({
render:h=>h(index)
}).$mount("#index")
/*index.scss*/
*{
margin: 0;
padding: 0;
}
html{
width: 100%;
}
/*index.vue*/
<template>
<div>2222</div>
</template>
项目依赖安装
webpack系列
-
webpack:是一个现代JavaScript应用程序的静态模块打包器(module bundler)。当webpack处理应用程序时,会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle
-
webpack-cli: webpack 4+ 版本必须
-
webpack-dev-server:是一个小型的Node.js Express服务器,使用webpack-dev-middleware来服务于webpack的包,除此自外,它还有一个通过Sock.js来连接到服务器的微型运行时。
-
webpack-merge:合并模块,用于合并对象以创建新对象
npm install webpack webpack-cli webpack-dev-server webpack-merge -D
loader系列
- css-loader/style-loader/postcss-loader:处理css样式及文件
npm install css-loader style-loader postcss-loader -D
- vue-loader/vue-template-compiler:加载和转译vue组件
npm install vue-loader vue-template-compiler -D
- file-loader:将文件发送到输出文件夹,并返回相对url
npm install file-loader -D
- babel-loader:加载 ES2015+ 代码,使用 Babel 转译为 ES5
npm install babel-loader@8.0.0-beta.0 @babel/core @babel/preset-env -D
- eslint-loader :使用eslint清理代码
npm install eslint eslint-loader -D
- sass-loader:加载和转译sass/scss文件
npm install sass-loader node-sass -D
插件系列
- html-webpack-plugin:可以生成创建html入口文件,比如单页面可以生成一个html文件入口,配置N个html-webpack-plugin可以生成N个页面入口
npm install html-webpack-plugin -D
- friendly-errors-webpack-plugin:可以识别某些类的webpack错误,并清除,汇总并确定优先级,以提供更好的开发人员体验。一款编译提示插件
npm install friendly-errors-webpack-plugin -D
- mini-css-extract-plugin:基于webpack4功能构建,用于将CSS提取到单独的文件中。它为每个包含CSS的JS文件创建一个CSS文件。它支持CSS和SourceMap的按需加载。
npm install mini-css-extract-plugin -D
- optimize-css-assets-webpack-plugin:用于优化/最小化css
npm install optimize-css-assets-webpack-plugin -D
- ora:一款好看的loading插件
npm install ora -D
- chalk:一款字体颜色插件
npm install chalk -D
- rimraf:用于删除已打包项目的npm包
npm install rimraf -D
vue系列
- vue:框架
npm install vue --save
npm脚本命令配置
配置package.json文件
"scripts": {
"start": "webpack-dev-server --config build/webpackDev.js",
"build": "node build/build.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
注:
-
执行npm run build 等于执行 node build/build.js:在本地进行开发
-
执行npm run start 等于执行 webpack-dev-server --config build/webpackDev.js:打包项目文件进行线上部署
配置文件
开发环境和生产环境的共同需求:
- 同样的入口、同样的代码处理(loader处理)、同样的解析配置
"use strict"
//引入node path路径模块
let path=require("path")
//引入node fs文件系统模块
const fs=require('fs')
//引入vue模板编译器vue-template-compiler,用于将vue2.0模板预编译为渲染函数,以避免运行时编译开销和csp限制,应与vue-loader搭配使用
let VueloaderPlugin=require("vue-loader/lib/plugin")
//引入插件html-webpack-plugin用于创建html入口文件
const HtmlWebpackPlugin = require('html-webpack-plugin')
//引入插件mini-css-extract-plugin用于抽离出css文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//判断是开发环境还是生产环境
const proMode=process.env.Node_ENV=='production'
//拼接路径
function resolve(dir){
return path.join(__dirname, '..',dir)
}
//配置多页面入口
//获取src/pages下面的所有文件夹
const page=fs.readdirSync(resolve('src/pages'))
let entryArr={}
let htmlplugin=[]
page.forEach(item=>{
//遍历生成入口文件并存储到entryArr对象中
entryArr[item]=`./src/pages/${item}/${item}.js`
//遍历生成相应的html文件存储到htmlplugin数组中
htmlplugin.push(
new HtmlWebpackPlugin({
entryName:item,
filename: `${item}.html`,
template: `./src/pages/${item}/${item}.html`,
//压缩配置
minify: {
//删除html注释
removeComments: true,
//去除空格
collapseWhitespace: true,
//去除属性引号
removeAttributeQuotes: true
}
})
)
})
module.exports={
//项目入口文件-webpack从此处开始构建
entry: entryArr,
//配置模块解析部分
resolve: {
//配置别名映射
alias: {
'@': resolve('src'),
'vue$': 'vue/dist/vue.esm.js',
'_c':resolve('src/component'),
'_p':resolve('src/pages'),
'_w':resolve('src/webgis/components')
},
//自动解析文件扩展名(补全文件后缀,从左往右)
//例:import home from './home',自动补全.js/.vue/.json
extensions: [".js",".vue",".json"]
},
//配置处理模块的规则,配置不同的loader处理不同的文件
module: {
rules: [
//使用babel-loader处理src下所有的js文件,具体babel配置在.babelrc,主要是用来转义es6
{
test: /\.js$/,
loader: "babel-loader",
include: resolve("src")
},
{
test: /\.js$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [resolve('src')]
},
{
test: /\.vue$/,
loader: "vue-loader"
},
{
test: /\.(sa|sc|c)ss$/,
use: [
proMode? MiniCssExtractPlugin.loader : 'style-loader',
"css-loader",
"sass-loader",
'postcss-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
"file-loader"
]
}
]
},
plugins: [
new VueloaderPlugin(),
...htmlplugin
]
}
开发环境的需求:
- 模块热更新 (本地开启服务,实时更新)
- sourceMap (方便打包调试)
- 接口代理 (配置proxyTable解决开发环境中的跨域问题)
- 代码规范检查 (代码规范检查工具)
//JavaScript严格模式(strict mode) 即在严格条件下运行,不严禁的代码会报错,从而消除语法不合理的怪异行为
"use strict"
//引入webpack配置合并模块,用于合并对象以创建新对象
const merge = require('webpack-merge')
//引入webpackBase通用配置文件
const webpackBase=require('./webpackBase')
//引入config文件的dev开发环境配置部分
const devConfig=require('./config').dev
//引入编译提示的webpack插件
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
module.exports=merge(webpackBase,{
mode:'development',
//项目出口,webpack-dev-server生成的包放在内存中,在项目是无法显示
output:{
path:'/dist'
},
//启动一个express服务器,在本地进行开发
devServer:{
//配置代理解决跨域
proxy:devConfig.proxy,
//配置主机名
host:devConfig.host,
//配置端口号
port:devConfig.port,
//开启热加载,代码保存后会自动刷新页面
hot:true
},
//webpack插件数组
plugins:[
//
new FriendlyErrorsPlugin({
//编译成功提示
compilationSuccessInfo: {
messages: [
`Your application is running here: http://${devConfig.host}:${devConfig.port}`
]
},
//编译失败提示
onErrors: function(severity, errors) {
if (severity !== "error") {
return;
}
const error = errors[0];
const filename = error.file.split("!").pop();
console.log(filename + ':' + error.name)
}
})
]
})
生产环境的需求:
- 提取公共代码
- 压缩混淆(压缩混淆代码,清除代码空格,注释等信息使其变得难以阅读)
- 文件压缩/base64编码(压缩代码,减少线上环境文件包的大小)
- 去除无用的代码
//JavaScript严格模式(strict mode) 即在严格条件下运行,不严禁的代码会报错,从而消除语法不合理的怪异行为
"use strict"
//引入node path路径模块
const path=require("path")
//引入webpack配置合并模块,用于合并对象以创建新对象
const merge=require("webpack-merge")
//引入webpackBase通用配置文件
const webpackBase=require("./webpackBase")
//引入config文件中build生产环境配置部分
const buildConfig=require("./config").build
//引入插件mini-css-extract-plugin,用于抽离出css文件
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//引入插件optimize-css-assets-webpack-plugin,用于压缩css文件
const OptimizeCSSPlugin = require("optimize-css-assets-webpack-plugin");
//配置资源路径函数
function assetsPath(_path){
return path.join('static',_path)
}
module.exports=merge(webpackBase,{
mode:'production',
output:{
path:path.resolve(__dirname,"../dist"),
filename:assetsPath("js/[name].[contenthash].js")
},
plugins:[
new MiniCssExtractPlugin({
filename: assetsPath('css/[name].[contenthash].css'),
chunkFilename: assetsPath('css/[id].[contenthash].css'),
ignoreOrder: false
}),
new OptimizeCSSPlugin(),
]
})