1、搭建webpack基础环境
1.1初始化项目
npm init
此时会生成一个webpack.json文件,主要是生成项目的基础信息
1.2安装webpack及手脚架
npm install webpack webpack-cli -D
-D命令要使用大写,否则识别不出来,会默认安装到生产环境中
2、开始配置功能
2.1配置ES6/7/8转ES5代码
npm install babel-loader @babel/core @babel/preset-env -D
- 新建一个build文件夹,用来存放webpack相关的文件
- 在build文件夹内新建一个webpack.config.js文件,配置webpack的基本配置
//webpack.config.js
const path = require('path')
module.exports = {
//指定打包模式
mode: 'development',
entry: {
//配置入口文件
main: path.resolve(__dirname, '../src/main.js')
},
output: {
//配置打包文件输出的目录
path: path.resolve(__dirname, '../dist'),
//生成的js文件名称
filename: 'js/[name].[hash:8].js',
//生成的chunk名称
chunkFilename: 'js/[name].[hash:8].js',
//资源引用路径
publicPath: './'
},
module: {
rules: [
{ //将js或者jsx文件转码成es5
test: /\.jsx?$/, // 正则惰性匹配后缀名为js或者jsx的文件
exclude: /node_modules/, //排除node_modules文件夹
loader: 'babel-loader',
options: {
presets:['@babel/preset-env']
}
}
]
}
}
新建src文件夹,在文件夹内创建一个main.js文件
//main.js
let name = "xiaoming";
console.log("hello" + name);
然后在package.json加入以下代码
"build": "webpack --config ./build/webpack.config.js"
执行以下命令会打包成一个dist文件,而且下面有一个由src/main.js
打包出来的main.js文件
npm run build
2.2使用 html-webpack-plugin
来创建html页面
安装html-webpack-plugin依赖
npm install html-webpack-plugin -D
在根目录下新建index.html文件,添加如下代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
修改webpack.config.js配置
//webpack.config.js
const path = require('path')
const HtmlWebpackplugin = require('html-webpack-plugin'); //++
module.exports = {
//指定打包模式
mode: 'development',
entry: {...
},
output: {...
},
module: {...
},
plugins:[ //++
new HtmlWebpackplugin({
filename: 'index.html', // 打包后的文件名,默认是index.html
template: path.resolve(__dirname, '../index.html') // 导入被打包的文件模板
})
]
}
运行npm run build
,我们可以看到dist
文件夹下有一个index.html
生成了,而且还引入了src/main.js
的压缩包main.js
2.4安装配置并使用vue
npm install vue-loader vue-template-compiler cache-loader thread-loader -D
npm install vue -S
vue-loader
用于解析.vue
文件vue-template-compiler
用于编译模板cache-loader
用于缓存loader
编译的结果thread-loader
使用worker
池来运行loader
,每个worker
都是一个node.js
进程。
修改webpack.config.js配置
//webpack.config.js
const path = require('path')
const VueLoaderPlugin = require('vue-loader/lib/plugin'); //++
const HtmlWebpackplugin = require('html-webpack-plugin');
module.exports = {
//指定打包模式
mode: 'development',
entry: {...
},
output: {...
},
module: {
rules: [
...
{ //++
test: /\.vue$/,
use: [
{
loader: 'cache-loader'
},
{
loader: 'thread-loader'
},
{
loader: 'vue-loader',
options: {
compilerOptions: {
preserveWhitespace: false
},
}
}
]
},
]
},
plugins:[
...
new VueLoaderPlugin() //++
]
}
在src里新建App.vue
<template>
<div class="App">
Hello {{msg}}
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
msg: "xiaoming",
};
}
};
</script>
修改src/main.js的代码:
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App)
}).$mount('#app')
再次运行npm run build
,然后在浏览器打开dist/index.html
,可以发现vue
已经可以运行了
2.4配置基础组件
npm install sass-loader dart-sass css-loader style-loader file-loader url-loader postcss-loader autoprefixer -D
sass-loader
,dart-sass
主要是将 scss/sass 语法转为csscss-loader
主要是解析 css 文件style-loader
主要是将 css 解析到html
页面 的style
上postcss-loader autoprefixer
实现自动添加css3
前缀
修改webpack.config.js
配置
//webpack.config.js
// ...
{
test: /\.(scss|sass)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader',
options: {
implementation: require('dart-sass')
}
},
{
loader: 'postcss-loader',
options: {
plugins: [
require("autoprefixer") /*自动添加前缀*/
]
}
}
]
},
{
test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 10000
}
}]
}
// ...
在src/App.vue后面加入下面样式代码:
...
<style lang="scss" scoped>
.App {
color: skyblue;
}
</style>
运行后,我们可以看到样式代码生效了
3、安装本地服务及代码热更新
安装webpack-dev-server
npm install webpack-dev-server -D
修改webpack.config.js配置
// ...
output: {
//配置打包文件输出的目录
path: path.resolve(__dirname, '../dist'),
//生成的js文件名称
filename: 'js/[name].[hash:8].js',
//生成的chunk名称
chunkFilename: 'js/[name].[hash:8].js',
//资源引用路径
publicPath: '/' //这里的./改成/
},
devServer: { //++
hot: true,
port: 8088
},
// ...
在package.json的scripts中增加一行启动本地服务指令:
"dev": "webpack-dev-server --progress --config ./build/webpack.config.js"
此时运行 npm run dev 可以启动本地服务,修改代码保存后,浏览器会自动进行更新
4、安装vue-router组件
安装vue-router
npm install vue-router --save
新增视图组件 在 src
目录下新增两个视图组件 src/views/page1.vue
和 src/views/page2.vue
// src/views/page1.vue
<template>
<div class="page1">
page1
</div>
</template>
// src/views/page2.vue
<template>
<div class="page2">
page2
</div>
</template>
在 src
目录下新增一个 router/index.js
文件
// src/router/index.js
import Vue from 'vue'
import VueRouter from "vue-router";
import page1 from '../view/page1.vue';
import page2 from '../view/page2.vue';
Vue.use(VueRouter)
export default new VueRouter({
mode: 'hash',
routes: [
{
path: '/page1',
component: page1
},
{
path: '/page2',
component: page2
},
{
path: '*',
redirect: '/page2'
}
]
})
修改 main.js
文件
// main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
router,
render: h => h(App)
}).$mount('#app')
修改 App.vue
组件
// App.vue
<template>
<div class="App">
<div>
Hello {{msg}}
</div>
<div>
<router-link to="/page1">go page1</router-link>
<router-link to="/page2">go page2</router-link>
</div>
<div>
<router-view></router-view>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
msg: "xiaoming",
};
}
};
</script>
<style lang="scss" scoped>
.App {
color: skyblue;
}
</style>
运行npm run dev命令,可以看到如下效果
4、区分开发环境和生产环境
在build文件下新建两个文件
webpack.dev.js
开发环境使用webpack.prod.js
生产环境使用webpack.config.js
公用配置
安装所需依赖
npm i @intervolga/optimize-cssnano-plugin mini-css-extract-plugin clean-webpack-plugin webpack-merge -D
- @intervolga/optimize-cssnano-plugin 用于压缩css代码
- mini-css-extract-plugin 用于提取css到文件中
- clean-webpack-plugin 用于删除上次构建的文件
- webpack-merge 合并 webpack配置
开发环境配置
const merge = require('webpack-merge')
const webpackConfig = require('./webpack.config')
const webpack = require('webpack')
module.exports = merge(webpackConfig, {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
module: {
rules: [
{
test: /\.(scss|sass)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
{
loader: 'sass-loader',
options: {
implementation: require('dart-sass')
}
},
{
loader: 'postcss-loader',
options: {
compilerOptions: {
preserveWhitespace: false
},
}
}
]
},
]
},
})
生产环境配置
const path = require('path')
const merge = require('webpack-merge')
const webpack = require('webpack')
const webpackConfig = require('./webpack.config')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssnanoPlugin = require('@intervolga/optimize-cssnano-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = merge(webpackConfig, {
mode: 'production',
devtool: '#source-map',
optimization: {
splitChunks: {
cacheGroups: {
vendors: {
name: 'chunk-vendors',
test: /[\\\/]node_modules[\\\/]/,
priority: -10,
chunks: 'initial'
},
common: {
name: 'chunk-common',
minChunks: 2,
priority: -20,
chunks: 'initial',
reuseExistingChunk: true
}
}
}
},
module: {
rules: [
{
test: /\.(scss|sass)$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
{
loader: 'sass-loader',
options: {
implementation: require('dart-sass')
}
},
{
loader: 'postcss-loader',
options: {
plugins: [
require("autoprefixer")
]
}
}
]
},
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:8].css',
chunkFilename: 'css/[name].[contenthash:8].css'
}),
new OptimizeCssnanoPlugin({
sourceMap: true,
cssnanoOptions: {
preset: [
'default',
{
mergeLonghand: false,
cssDeclarationSorter: false
}
]
}
}),
new CleanWebpackPlugin()
]
})
公共配置
//webpack.config.js
const path = require('path')
const HtmlWebpackplugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
//指定打包模式
mode: 'development',
entry: {
//配置入口文件
main: path.resolve(__dirname, '../src/main.js')
},
output: {
//配置打包文件输出的目录
path: path.resolve(__dirname, '../dist'),
//生成的js文件名称
filename: 'js/[name].[hash:8].js',
//生成的chunk名称
chunkFilename: 'js/[name].[hash:8].js',
//资源引用路径
// publicPath: './'
},
devServer: { //node本地服务器
hot: true,
port: 8088
},
module: {
rules: [
{ //将js或者jsx文件转码成es5
test: /\.jsx?$/, // 正则惰性匹配后缀名为js或者jsx的文件
exclude: /node_modules/, //排除node_modules文件夹
use: {
loader: 'babel-loader',
options: {
presets:['@babel/preset-env']
}
}
},
{
test: /\.vue$/,
use: [
{
loader: 'cache-loader'
},
{
loader: 'thread-loader'
},
{
loader: 'vue-loader',
options: {
compilerOptions: {
preserveWhitespace: false
},
}
}
]
},
{
test: /\.(png|jpg|jpeg|gif|eot|ttf|woff|woff2|svg|svgz)(\?.+)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 10000
}
}]
}
]
},
plugins:[
new VueLoaderPlugin(),
new HtmlWebpackplugin({
filename: 'index.html', // 打包后的文件名,默认是index.html
template: path.resolve(__dirname, '../index.html') // 导入被打包的文件模板
})
]
}