内容简介:大致如下:大致如下:在两个环境下,需要把通用的配置合并,所以需要用到
- 在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)、热模块替换(hot module replacement)能力的 source map(方便开发者调试代码) 和 localhost server(本地服务器)。
大致如下:
- webpack-dev-server实时重载、热替换
- 不压缩代码
- css样式不提取至单独的文件中
- 使用sourceMap配置,将源码映射会原始文件(方便调试)
- 不压缩html
生产环境
- 在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。。
大致如下:
- 不需要实时重载、热替换
- 压缩js、css
- css样式提取至单独的文件中
- sourceMap.
- 代码分离(optimization)
- 压缩html
- 资源缓存(NamedChunksPlugin、HashedModuleIdsPlugin)
- 清除dist目录文件
解决通用代码
在两个环境下,需要把通用的配置合并,所以需要用到 webpack-merge
合并工具,解决代码重复的问题。
安装 webpack-merge
npm i webpack-merge -D 复制代码
最新目录、文件
lesson-05
|- build
|- webpack.base.conf.js // + 通用配置
|- webpack.dev.conf.js // + 开发环境配置
|- webpack.prod.conf.js // + 生产环境
|- node-modules
|- pubilc
|- package.json
|- package-lock.json
|- src
|- print.js // + 用于测试缓存
|- favicon.ico // + 网页icon
复制代码
安装生产环境相关包
npm i cross-env copy-webpack-plugin mini-css-extract-plugin optimize-css-assets-webpack-plugin uglifyjs-webpack-plugin -D 复制代码
- cross-env:在命令行中配置环境变量(查看package.json)
- copy-webpack-plugin:拷贝资源
- mini-css-extract-plugin:单独提取至css文件
- optimize-css-assets-webpack-plugin:压缩css文件
- uglifyjs-webpack-plugin:压缩js文件
通用配置
webpack.base.conf.js
const path = require('path')
const webpack = require('webpack')
const { VueLoaderPlugin } = require('vue-loader')
const resolve = (dir) => path.resolve(__dirname, dir)
const jsonToStr = (json) => JSON.stringify(json)
const isProd = process.env.NODE_ENV === 'production'
module.exports = {
// 入口配置
entry: {
app: ['@babel/polyfill', resolve('../src/main.js')]
},
// 打包输出配置
output: {
path: resolve('../dist'),
filename: 'bundle.js' // filename是相对于path路径生成
},
// 引入资源省略后缀、资源别名配置
resolve: {
extensions: ['.js', '.json', '.vue'],
alias: {
'@': resolve('../src')
}
},
// 定义模块规则
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
// 指定目录去加载babel-loader,提升运行、打包速度
include: [resolve('../src'), resolve('../node_modules/webpack-dev-server/client')],
// 排除目录,提升运行、打包速度
exclude: file => (
/node_modules/.test(file) &&
!/\.vue\.js/.test(file)
)
},
{
test: /\.(png|svg|jpg|gif)$/,
loader: 'file-loader',
options: {
// 指定生成的目录
name: 'static/images/[name].[hash:7].[ext]',
},
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
// 插件选项
plugins: [
// 定义环境变量
new webpack.DefinePlugin({
'process.env.NODE_ENV': isProd ? jsonToStr('production') : jsonToStr('development')
}),
new VueLoaderPlugin()
]
}
复制代码
开发环境配置
webpack.dev.conf.js
const path = require('path')
const webpack = require('webpack')
const merge = require('webpack-merge')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const baseWebpack = require('./webpack.base.conf')
const resolve = (dir) => path.resolve(__dirname, dir)
module.exports = merge(baseWebpack, {
mode: 'development',
devtool: 'cheap-source-map', // 开启cheap-source-map模式调试
// 开启web服务器、热更新
devServer: {
open: true,
hot: true,
port: 3002,
publicPath: '/',
contentBase: resolve("../dist") // 设置dist目录为服务器预览的内容
},
// 定义模块规则
module: {
rules: [
{
test: /\.(css|scss|sass)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'sass-loader',
options: {
implementation: require('dart-sass')
}
},
{
loader: 'postcss-loader'
}
]
}
]
},
// 插件选项
plugins: [
// html模板、以及相关配置
new HtmlWebpackPlugin({
title: 'Lesson-06',
template: resolve('../public/index.html')
}),
// 热替换插件
new webpack.HotModuleReplacementPlugin(),
// 在热加载时直接返回更新文件名,而不是文件的id。
new webpack.NamedModulesPlugin()
]
})
复制代码
生产环境配置
webpack.prod.conf.js
const path = require('path')
const merge = require('webpack-merge')
const webpack = require('webpack')
const webpackConfig = require('./webpack.base.conf')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const resolve = (dir) => path.resolve(__dirname, dir)
module.exports = merge(webpackConfig, {
mode: 'production',
devtool: false,
// 运行、打包输出配置
output: {
path: resolve('../dist'),
filename: 'static/js/[name].[chunkhash:8].js'
},
// 压缩js、css资源、分包
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs', // 打包后生成的js文件名称
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // 只打包初始时依赖的第三方
},
// elementUI选项暂时未使用到(参考elementUI中的配置)
elementUI: {
name: 'chunk-elementUI', // 单独将 elementUI 拆包
priority: 21, // 权重要大于 libs 和 app 不然会被打包进 libs 或者 app
test: /[\\/]node_modules[\\/]element-ui[\\/]/
},
// commons选项暂时未使用到(参考elementUI中的配置)
commons: {
name: 'chunk-commons',
test: resolve('../src/components'), // 可自定义拓展你的规则
minChunks: 3, // 最小公用次数
priority: 5,
reuseExistingChunk: true
}
}
},
runtimeChunk: 'single',
minimizer: [ // 压缩js、压缩css配置
new UglifyJsPlugin({
sourceMap: false,
cache: true,
parallel: true
}),
new OptimizeCSSAssetsPlugin()
]
},
// 定义模块规则
module: {
rules: [
{
test: /\.(scss|sass)$/,
use: [
{
loader: MiniCssExtractPlugin.loader
},
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: false
}
},
{
loader: 'sass-loader',
options: {
implementation: require('dart-sass'),
sourceMap: false
}
},
{
loader: 'postcss-loader',
options: {
sourceMap: false
}
}
]
},
]
},
// 插件选项
plugins: [
// 清除上次构建的文件,清除目录是基于output出口目录
new CleanWebpackPlugin(),
// 创建html入口,无需手动引入js、css资源
new HtmlWebpackPlugin({
template: resolve('../public/index.html'),
title: 'Lesson-06',
favicon: resolve('../favicon.ico'),
// 压缩html
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
}),
// 提取至单独css文件
new MiniCssExtractPlugin({
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].css'
}),
// 拷贝资源
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../public'),
to: path.resolve(__dirname, '../dist')
}
]),
// 当chunk没有名字时,保持chunk.id稳定(缓存chunk)
new webpack.NamedChunksPlugin(chunk => {
if (chunk.name) {
return chunk.name
}
const modules = Array.from(chunk.modulesIterable)
if (modules.length > 1) {
const hash = require('hash-sum')
const joinedHash = hash(modules.map(m => m.id).join('_'))
let len = 4
const seen = new Set()
while (seen.has(joinedHash.substr(0, len))) len++
seen.add(joinedHash.substr(0, len))
return `chunk-${joinedHash.substr(0, len)}`
} else {
return modules[0].id
}
}),
// 当vender模块没有变化时,保持module.id稳定(缓存vender)
new webpack.HashedModuleIdsPlugin()
]
})
复制代码
动态CDN资源配置
在参考别人的配置过程中,发现一个可以在webpack中自定义配置CDN的方式,主要是利用 html-webpack-plugin
插件的能力,可以新增自定义属性,将CDN资源链接,配置至此自定义属性中。通过在 index.html
模板中遍历属性来自动生成CDN资源引入。
如下:
webpack.dev.conf.js、webpack.prod.conf.js
...省略
// 插件选项
plugins: [
// html模板、以及相关配置
new HtmlWebpackPlugin({
title: 'Lesson-06',
template: resolve('../public/index.html'),
// cdn(自定义属性)加载的资源,不需要手动添加至index.html中,
// 顺序按数组索引加载
cdn: {
css:['https://cdn.bootcss.com/element-ui/2.8.2/theme-chalk/index.css'],
js: [
'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',
'https://cdn.bootcss.com/element-ui/2.8.2/index.js'
]
}
})
]
...省略
复制代码
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title><%= htmlWebpackPlugin.options.title %></title>
<!-- import cdn css -->
<% if(htmlWebpackPlugin.options.cdn) {%>
<% for(var css of htmlWebpackPlugin.options.cdn.css) { %>
<link rel="stylesheet" href="<%=css%>">
<% } %>
<% } %>
</head>
<body>
<div id="box"></div>
<!-- import cdn js -->
<% if(htmlWebpackPlugin.options.cdn) {%>
<% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%=js%>"></script>
<% } %>
<% } %>
</body>
</html>
复制代码
配置开发、生产环境命令
在package.json的scripts选项中新增,dev、build命令,分别是开发环境、生产环境的命令,
package.json
{
"name": "lesson-06",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"dev": "npx webpack-dev-server --config ./build/webpack.dev.conf.js",
"build": "cross-env NODE_ENV=production npx webpack --config ./build/webpack.prod.conf.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.4.4",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.4.4",
"autoprefixer": "^9.5.1",
"babel-loader": "^8.0.5",
"clean-webpack-plugin": "^2.0.1",
"copy-webpack-plugin": "^5.0.3",
"cross-env": "^5.2.0",
"css-loader": "^2.1.1",
"dart-sass": "^1.19.0",
"file-loader": "^3.0.1",
"html-webpack-plugin": "^3.2.0",
"mini-css-extract-plugin": "^0.6.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"uglifyjs-webpack-plugin": "^2.1.2",
"vue-loader": "^15.7.0",
"vue-template-compiler": "^2.6.10",
"webpack": "^4.30.0",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.3.1",
"webpack-merge": "^4.2.1"
},
"dependencies": {
"vue": "^2.6.10"
}
}
复制代码
以上所述就是小编给大家介绍的《webpack4-06-开发、生产环境、动态CDN配置》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Making Things See
Greg Borenstein / Make / 2012-2-3 / USD 39.99
Welcome to the Vision Revolution. With Microsoft's Kinect leading the way, you can now use 3D computer vision technology to build digital 3D models of people and objects that you can manipulate with g......一起来看看 《Making Things See》 这本书的介绍吧!