一、WebPack
webpack的两大特点:1模块化 2打包
作用:
1将sass/less 等预编译的css语言转换成浏览器识别的css文件
2能够将多个预编译文件打包成一个文件
3 打包image/styles/assets/scrips/等前端常用的文件
4 搭建开发环境开启服务器
5 监视文件改动,热部署。
6 将单文件组件(*.vue)类型的文件,转化成浏览器识别的内容
1. 安装webpack:
$ npm i -D webpack webpack-cli //-D 安装在开发环境
WebPack 4.X 支持零配置 (我们先来尝试一下webpack如何实现打包部署)
$ npx webpack //基于npx执行了webpack命令,而这个命令就是实现打包部署的
查找顺序:
- 找到node_modules/.bin
- 要求我们得有 webpack.cmd 的文件
- 执行 webpack.cmd
知识点:自npm5.2.0开始以后,自动安装了npx( npx 会帮你执行依赖包里的二进制文件)
举个例子:(在npx没有出现之前)
npm i webpack -D //非全局安装//如果要执行 webpack 的命令./node_modules/.bin/webpack -v
有了npx后
npm i webpack -D //非全局安装npx webpack -v
npx 会自动查找当前依赖包中的可执行文件,如果找不到,就会去 PATH 里找。如果依然找不到,就会帮你安装。
2. webpack 自定义配置
虽然webpack支持零配置,但是日常开发中我们也会根据需求来自己定义基础配置
在根目录下创建webpack.config.js文件:
/*
* 在这个文件中设置我们自定义的打包规则
* 1.所有的规则都写在module.exports={}中
*/
//因为需要用node中的path内置模块(内置模块,无需下载)
let path = require('path');
module.exports = {
//=>打包模式 开发环境development 生产环境production
mode: 'production',
//=>入口
entry: './src/index.js',
//=>输出
output: {
//=>输出文件的文件名
filename: 'bundle.min.[hash].js',
//=>输出目录的"绝对路径"
path: path.resolve(__dirname, 'dist')
}
}
3. 自定义配置文件名
我们可以在根目录下package.json文件中
//package.json
"scripts": {
"serve": "webpack-dev-server --config webpack.config.development.js",
"build": "webpack --config webpack.config.development.js"
}
//这样我们以后就可以通过 yarn或者npm直接执行 serve/build 了,方便了很多
4. webpack-dev-server:
是一个用来快速搭建本地运行环境的工具。命令简单webpack-dev-server
或配置命令脚本快捷运行(在👆3中 已经配置了serve,我们以后可以直接运行 serve)
安装
$ yarn add webpack-dev-server -D
//=>关于webpack-dev-server的一些配置
执行命令:webpack-dev-server --config xxx.js(特点:服务器启动后,默认是不关闭的,当我们修改SRC中的文件时,它会自动进行编译,然后自动刷新浏览器)
devServer: {
port: 3000, //=>创建服务指定的端口号
progress: true, //=>显示打包编译的进度
contentBase: './build', //=>指定当前服务处理资源的目录
open: true //=>编译完成后会自动打开浏览器
}
-
$ npm run serve $ yarn serve $ npx webpack-dev-server
5. html-webpack-plugin:
html-webpack-plugin
插件是用于编译 Webpack
项目中的 html 类型的文件,如果直接将 html
文件置于 ./src
目录中,用 Webpack
打包时是不会编译到生产环境中的。因为 Webpack
编译任何文件都需要基于配置文件先行配置的。
Webpack 插件使用三步曲:安装>引入>配置
npm&yarn 安装
$ npm install --save-dev html-webpack-plugin
$ yarn add html-webpack-plugin --dev
引入(接着在webpack.config.js 开始的地方引入)
let HtmlWebpackPlugin = require('html-webpack-plugin');
配置
module.exports = {
...,
//=>在webpack中使用插件
plugins: [
//因为导入的插件是一个类,所以我们用的时候需要new 一下
new HtmlWebpackPlugin({
//=>指定自己的模板
template: './src/index.html',
//=>输出的文件名
filename: 'index.html',
//=>给引入的文件设置HASH戳(清除缓存的),也可以在output中设置 filename: 'bundle.[hash].js' 来生成不同的文件
hash: true,
//=>控制是否以及以何种方式最小化输出
//=>https://github.com/kangax/html-minifier
//控制压缩
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true,
removeEmptyAttributes: true
}
})
]
}
6. 使用加载器loader处理规则(处理样式)
官网: www.webpackjs.com/api/loaders…
安装
$ yarn add css-loader style-loader less less-loader autoprefixer postcss-loader (等等) -D
配置
module.exports = {
//=>配置模块加载器LOADER
module: {
//=>模块规则:使用加载器(默认从右向左执行,从下向上)
rules: [{
test: /\.(css|less)$/, //=>基于正则表达式匹配哪些模块需要处理
use: [
"style-loader", //=>把CSS插入到HEAD中
"css-loader", //=>编译解析@import/URL()这种语法
"postcss-loader", //=>设置前缀
{
loader: "less-loader",
options: {
//=>加载器额外的配置
}
}
]
}]
}
}
在 postcss.config.js 文件中
//这个文件需要配合postcss-loader使用
module.exports = {
plugins: [
require('autoprefixer')
]
};
在 package.json 文件的末尾加入
//像这些" > 1%", "last 2 versions" 都是查询参数
"browserslist": [
"> 1%",
"last 2 versions"
]
7. mini-css-extract-plugin 抽离CSS内容 (单独把css隔离出来并压缩)
安装
$ yarn add mini-css-extract-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D
引入
let MiniCssExtractPlugin = require('mini-css-extract-plugin'),
OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'),
UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin');
配置
module.exports = {
//=>设置优化项
optimization: {
//=>设置压缩方式
minimizer: [
//=>压缩CSS(但是必须指定JS的压缩方式)
new OptimizeCssAssetsWebpackPlugin(),
//=>压缩JS
new UglifyjsWebpackPlugin({
cache: true, //=>是否使用缓存
parallel: true, //=>是否是并发编译
sourceMap: true, //=>启动源码映射(方便调试)
})
]
},
plugins: [
//=>使用插件
new MiniCssExtractPlugin({
//=>设置编译后的文件名字
filename: 'main.css'
})
],
module: {
rules: [{
test: /\.(css|less)$/,
use: [
// "style-loader",
//=>使用插件中的LOADER代替STYLE方式
MiniCssExtractPlugin.loader,
"css-loader",
"postcss-loader",
"less-loader"
]
}]
}
}
8. 基于babel实现ES6的转换和ESLint语法检测
(当我们需要对于ES6中的一些语法进行处理)
安装
$ yarn add babel-loader @babel/core @babel/preset-env @babel/plugin-proposal-class-properties @babel/plugin-proposal-decorators @babel/plugin-transform-runtime -D
$ yarn add @babel/runtime @babel/polyfill
$ yarn add eslint eslint-loader -D
配置
module.exports = {
...,
module: {
rules: [...,{
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
//=>转换的语法预设(ES6->ES5)
presets: [
"@babel/preset-env"
],
//=>基于插件处理ES6/ES7中CLASS的特殊语法
plugins: [
["@babel/plugin-proposal-decorators", {
"legacy": true
}],
["@babel/plugin-proposal-class-properties", {
"loose": true
}],
"@babel/plugin-transform-runtime"
]
}
}], //=>, "eslint-loader"
//=>设置编译时忽略的文件和指定编译目录
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
}]
}
}
9. 暴露全局 loader
(如果你想直接使用 jQuery或者 $)
安装
$ yarn add expose-loader -D
配置
//=>内联加载器
import jquery from 'expose-loader?$!jquery'; //这句话的意思就是将jquery以$的形式暴露给window
{
//=>只要引入JQUERY就在全局注入$
test: require.resolve('jquery'),
use: ['expose-loader?$']
}
let webpack = require('webpack');
module.exports = {
plugins: [
//=>在每个模块中都注入$
new webpack.ProvidePlugin({
'$': 'jquery'
})
],
}
//=>页面中
console.log($);//这样就不会报错了
10. webpack中图片的处理和分目录分发
(当我们js中创建img,css设置图片以及HTML页面中写入的图片,可以基于此方法压缩)
安装
$ yarn add file-loader url-loader html-withimg-loader -D
配置
module.exports = {
...,
module: {
//=>模块规则:使用加载器(默认从右向左执行)
rules: [..., {
//还有很多图片格式。。。
test: /\.(png|jpg|gif)$/i,
use: [{
//=>把指定大小内的图片BASE64
loader: 'url-loader',
options: {
limit: 200 * 1024,//=>只要图片是小于200KB,在处理的时候直接给BASE64
outputPath:'/images'//控制打包后图片所在的目录
}
}],
include: path.resolve(__dirname, 'src'),
exclude: /node_modules/
}, {
//=>处理HTML文件中导入的IMG图片
test: /\.html$/,
use: ['html-withimg-loader']
}]
}
}
11. 文件分目录发布
module.exports = {
output: {
//=>配置引用前缀(所有资源前加这个地址)
publicPath: './'
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/main.css'
})
],
module: {
//=>模块规则:使用加载器(默认从右向左执行)
rules: [...,{
test: /\.(png|jpg|gif)$/i,
use: [{
options: {
outputPath: 'images'
}
}]
}]
}
}
到此 webpack 的各种配置 已经可以完成日常开发了
Vue-Cli 脚手架
在写这个文章之前我只是知道可以用vue-cli直接生成一个vue项目的架构,并不明白,他究竟是怎么运行的☺
1.什么是CLI
2.安装
npm install -g @vue/cli //-g 全局
# OR
yarn global add @vue/cli //基于yarn安装(需要安装yarn)
3.创建一个vue-cli项目
$vue create [项目名称](要遵循npm包的名称规范:数字或者小写字母)
你会被提示选取一个 preset。你可以选默认的包含了基本的 Babel + ESLint 设置的 preset,也可以选“手动选择特性”来选取需要的特性。
选择第二个 Manually select features
可以按照这个 配置自己需要的 方向键 ↑↓ 可以选择 space 空格键确认 除了默认选择的两项我还选择了Router,Vuex,CSS Pre-processore(根据自己需求选择,后期也可以自己添加)
等待安装,项目基本就算创建完成了
然后你就看到自己创建的项目了 用编辑器打开hello--xiaokai文件
你可以打开自己编辑器的终端 我用的是VScode ctrl+` 然后输入
$npm run serve 或者 $yarn serve
就可以把项目预览了
4.编译打包
在生产模式下,把写好的内容进行编译打包,最后部署到服务器上
$npm run build or $yarn build
--Webpack完整版
/*
在这个文件中设置我们自定义的打包规则
1. 所有的规则都写在module.exports={}中
*/
let path = require('path');
let HtmlWebpackPlugin = require('html-webpack-plugin');
let MiniCssExtractPlugin = require('mini-css-extract-plugin'), //把css单独分离出来
OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin'), //压缩css
UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin'); //压缩js
let webpack = require('webpack');
//导入进来的插件都是一个类 new HtmlWebpackPlugin({});
module.exports = {
//配置优化规则
optimization: {
//设置压缩方式
minimizer: [
//压缩css (产生问题:JS压缩不在执行自己默认的压缩方式了,也走的是这个插件,从而导致无法压缩,所以必须设置JS的压缩方式)
new OptimizeCssAssetsWebpackPlugin(),
//压缩js
new UglifyjsWebpackPlugin({
cache: true, //是否使用缓存
parallel: true, //是否是兵法编译
sourceMap: true, //启动源码映射(方便调试)
})
]
},
//配置环境 开发环境development 生产环境production(默认)
mode: 'production',
//入口 @babel6
entry: ['@babel/polyfill', './src/index-my.js'],
//出口
output: {
//输出文件的文件名
//bundle.min.[hash].js 让每一次生成的文件名都带着hash值
filename: 'bundle.min.js',
// filename: 'bundle.min.[hash].js',
//输出的目录必须是绝对路径,__dirname当前目录
path: path.resolve(__dirname, 'dist'),
publicPath: './' //给编译后引入资源地址前面设置的前缀
},
//关于webpack-dev-server的一些配置 执行命令:webpack-dev-server --config xxx.js (特点:服务启动后,默认是不关闭的,当我们修改src中的源文件,他会自动进行编译,然后自动刷新浏览器,类似于vscode中的Live Server插件,实时刷新)
devServer: {
//创建服务指定的端口号
port: 3000,
//显示打包编译进度
progress: true,
//指定当前服务处理资源的目录
contentBase: './dist',
//编译完成后,自动打开浏览器
open: true
},
//使用插件 (数组)
plugins: [
new HtmlWebpackPlugin({
//不指定模版会按照默认模版创建一个html页面,当然真实项目中一般都是把自己写好的html进行编译
template: './src/index.html',
//输出的文件名
filename: 'index.html',
//让我们引入js后面加上hash戳(清除缓存),但是真实项目中我们一般都是每一次编译生成不同的js文件引入
hash: true,
//控制压缩
minify: {
collapseWhitespace: true,
removeComments: true,
removeAttributeQuotes: true,
removeEmptyAttributes: true
}
}),
new MiniCssExtractPlugin({
//指定输出的文件名
filename: 'main.min.css'
}),
//在每个模块中都注入$
new webpack.ProvidePlugin({
'$': 'jquery'
}),
],
//使用加载器loader处理规则
module: {
rules: [{
//基于正则匹配处理哪些文件
test: /\.(css|less)$/,
//使用哪一个加载器,控制使用的loader(有顺序的:从右到左执行)
use: [
// "style-loader", //把编译好的css插入到页面的head中(内嵌式)
MiniCssExtractPlugin.loader, //使用插件中的loader代替style方式
"css-loader", //编译解析@import/URL()这种语法
// "postcss-loader",//设置前缀的加载器
{
loader: "postcss-loader",
options: {
ident: 'postcss',
plugins: [
require('autoprefixer')
]
}
},
{
loader: "less-loader", //编译less
options: {
//加载额外的配置
}
}
]
}, {
test: /\.js$/,
//处理编译JS的loader
use: [{
loader: 'babel-loader',
options: {
//转换的语法预设(ES6->ES5)
presets: [
"@babel/preset-env"
],
//=>基于插件处理ES6/ES7中CLASS的特殊语法
plugins: [
["@babel/plugin-proposal-decorators", {
"legacy": true //处理装饰器
}],
["@babel/plugin-proposal-class-properties", {
"loose": true //处理属性
}],
"@babel/plugin-transform-runtime"
]
}
}],
//设置编译时忽略的文件和指定编译目录
include: path.resolve(__dirname, 'src'), //编译的
exclude: /node_modules/ //忽略的·
}, {
//图片处理
test: /\.(png|jpg|gif|jpeg|ico|webp|bpm)$/i,
use: [{
loader: 'url-loader',
options: {
//只要图片小于200KB,在处理的时候直接base64
limit: 2 * 1024,
//控制打包后图片所在的目录
outputPath: 'images'
}
}]
}, {
//处理HTML文件中导入的img文件
test: /\.(html|htm|xml)$/i,
use: ['html-withimg-loader']
}]
}
}