前言
咱们在应用 webpack
时,常常会看到相似以下构造:
build
├── webpack.common.js
└── webpack.dev.js
└── webpack.prod.js
很多时候,webpack
的配置咱们根本复制粘贴过去的,没有想过为什么咱们要把配置文件拆解成这么多。因而,当咱们本人去学习配置 webpack
时,咱们常常会呈现以下等问题:
- 开发环境构建速度慢
- 打包后页面空白
- 资源找不到
其实这些问题,都源于咱们:
- 不了解
webpack
构建开发环境、生产环境,两种环境配置的思维差别 - 对两种环境输入的文件目录,脑海中没有一个清晰的了解
所以本文还是跟以前一样,不会一味的把配置复制过去,而是心愿 总结相干办法,让大家更好学会配置。
后期筹备
因为讲的是配置,所以心愿你对 webpack
有一些根底。如果你只是刚学习 webpack
,倡议先浏览一下前两篇文章, 尤其是第二篇:
- 弄懂这几个概念后,我对 webpack 有了更新的了解:学习应用
webpack
时波及到的一些概念,让咱们对webpack
整体有个大抵的理解 - 有了这些办法,webpack 你也能够本人配:总结配置
webpack
时的一些办法。通过这些办法,咱们能够很好的了解webpack
的一些根底配置该如何配置
学习纲要
这篇文章次要解说:
webpack
开发环境配置的核心思想- 依据核心思想,实现一个开发环境配置
- 解析
devServer
配置项一些容易混同的点 - 总结
webpack
开发环境配置外围
备注
文章波及到的案例曾经上传到 github:
- 为了浏览不便,文章只贴了相干代码,倡议
fork
一下,看看残缺代码;或者跟着文章一起边看边敲,这样印象会更粗浅一些 - 创作不易,如果感觉有帮忙的话,欢送
star
🌟
开发环境核心思想
在上文咱们提到,咱们在应用 webpack
时,常常会看到相似以下目录:
build
├── webpack.common.js
└── webpack.dev.js
└── webpack.prod.js
为什么咱们须要把配置文件拆解成这么多,那么繁琐呢?
咱们先回顾一下,在咱们在理论开发中,为了我的项目可能稳固平安上线,咱们个别会分好几个环境:
- 开发环境:在本地进行开发,调试的环境
- 测试环境:咱们在本地开发实现后,将代码部署到咱们的测试服务器,进行测试
- 生产环境:测试通过,将代码部署到正式服务器,正式上线
有些更严格的测试,还会有预生产环境等
咱们的配置应该对环境具备针对性,因而不同的环境,咱们的配置当然不能千篇一律。
目标
咱们要先分明开发环境基本的目标是什么。
开发环境的基本目标,就是在开发过程中,能疾速定位到问题,更快能看到成果调试,进步开发效率。
尤其作为前端,离不开跟视觉打交道。咱们巴不得 Ctrl+S
后,立马出成果,不便咱们疾速调试。试想一下,如果每次写完一个成果,要等上几秒钟能力看到,这会不会把咱们逼疯?
思维
因而,为了能让咱们尽快看到成果调试,缩小 webpack
的编译过程,开发环境,配置应该所有从简:
- 对款式,咱们不须要拆散,间接用
style-loader
插入到<head />
- 对
js
、img
、media
、font
等前端资源文件,不须要分包 - 开启
source map
,不便定位问题 - 应用
webpack
提供的devServer
配置项,进行本地开发 - 不要压缩代码
- 不必没必要的
loader
跟plugins
- …
开发环境配置,也因人而异,以上是我的做法。然而咱们要记得,开发环境,配置应该所有从简,为了让咱们可能更快看到成果,进步开发效率
开发环境配置
初体验
通过前一篇文章的解说,置信大家对 webpack
的根底配置:
- 解决
css、less
、前端资源等文件 - 编译
es6+
语法及api
- 解决
html
文件
曾经把握了相干的配置办法,并且咱们还总结了一份根底的配置,不太分明的同学能够看一下先,这个根底配置还是蛮重要的。
ok,那咱们先用 learn-08 这个案例来体验一下如何进行本地开发调试。为了尽量贴近咱们事实中开发的我的项目,案例里会:
- 在
html
外面援用图片 - 应用
less
外面援用图片 - 在
js
里应用es6+
,动静加载图片 - 应用
devServer
配置项
为了浏览不便,具体的源码就不放文章了,大家能够去 github 看
而后进行以下步骤:
- 为了语义化,咱们把
webpack
配置文件命名为webpack.dev.js
-
应用命令行启动
webpack
——npm start
"scripts": {"start": "webpack server --config ./webpack.dev.js"}
运行后果:
咱们会发现:
- 文件编译解决实现后,不会输入任何文件
- 此时开启了一个外部服务器(
http://192.168.0.196:8080/
)。如果咱们的手机与电脑用的同个网络,用手机拜访这个链接,就能看到成果了。这对调试H5
开发是非常高效的(这次要归功于deveServer
配置项,后文会有解说) - 咱们批改代码后,页面会实时更新
以上简直是咱们想要的高效开发成果。
剖析
初步体验完后,咱们依据上文总结的开发环境配置思维,来看看对开发环境该如何配置:
-
解析款式不须要拆散出
css
文件,咱们间接将解析进去的款式插入到<header />
中:module: { rules: [ {test: /.(css|less)$/, use: [ 'style-loader', 'css-loader', 'less-loader' ] }, ] },
-
对
js
、img
、media
、font
等前端资源文件,不须要分包:output: {path: path.resolve(__dirname, './dist'), filename: '[name]-[chunkhash:5].js', }, module: { rules: [ {test: /\.(png|svg|jpg|jpeg|gif)$/i, type: 'asset', parser: { dataUrlCondition: {maxSize: 1024 * 3 // When the image size is < 3kb it will be converted to base64} }, generator: {filename: '[name]-[hash:5][ext]' // Set the name of the output file } }, { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: {loader: 'babel-loader'} } ] },
-
开启
source map
,不便定位问题;并且不压缩代码:{ mode: 'development', devtool: 'inline-cheap-module-source-map' }
-
应用
webpack
提供的devServer
进行本地开发:devServer: { static: {directory: path.join(__dirname, 'static'), }, },
-
没有装置其余多余的
plugin
,因为要解析html
,所以只装置了解析html
的plugin
plugins: [ new HtmlWebpackPlugin({filename: path.resolve(__dirname, './dist/[name].html'), template: path.resolve(__dirname, './src/index.html'), title: 'webpack.dev.config', }) ],
咱们比照一下根底配置,会发现 开发环境配置跟根底配置简直没差异,只是多应用了
devServer
配置项,来开启本地服务器调试:
// webpack.dev.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
+ mode: 'development',
+ devtool: 'inline-cheap-module-source-map',
entry: {index: './src/index.js'},
output: {path: path.resolve(__dirname, './dist'),
filename: '[name]-[chunkhash:5].js',
},
module: {
rules: [
{test: /.(css|less)$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
},
{test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset',
parser: {
dataUrlCondition: {maxSize: 1024 * 3 // When the image size is < 3kb it will be converted to base64}
},
generator: {filename: '[name]-[contenthash:5][ext][query]' // Set the name of the output file
}
},
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {loader: 'babel-loader'}
}
]
},
plugins: [
new HtmlWebpackPlugin({filename: path.resolve(__dirname, './dist/[name].html'),
template: path.resolve(__dirname, './src/index.html'),
title: 'webpack.dev.config',
})
],
+ devServer: {
+ static: {+ directory: path.join(__dirname, 'static'),
+ },
+ }
}
devServer
还记得咱们之前的案例,是怎么运行咱们的代码的吗?咱们都是打包完当前,用自带的编辑器(vscode
)运行查看后果的。要是咱们平时开发是这么低效的话,那预计我的项目不必上线了。
因而 webpack
提供了一个非常人性化的配置项——devServer
。
想应用这个配置项,咱们须要先
npm i webpack-dev-server -D
装置webpack-dev-server
依赖
从这么语义化的名字就晓得,它必定是开发环境下,能够提供某种服务的配置。
这个服务就是,这将会开启一个本地服务,将咱们配置的webpack
,实时编译,保留在内存中,这样能够不便调试咱们的代码,这很好的满足了咱们本地开发须要高效的目标。
因而这个配置项,只用于咱们开发环境配置
devServer.static
文档解释:通知服务器从哪里提供内容。只有在你心愿提供动态文件时才须要这样做
谬误了解
devServe
配置项,其实文档曾经写的挺具体了,这里讲一个可能容易混同的配置项——devServe.static
。
很多人应用webpack
,都是复制粘贴,所以常常会看到上面这种配置:
output: {path: path.resolve(__dirname, './dist'),
}
devServer: {
static: {directory: path.join(__dirname, 'dist'),
}
}
因为咱们设置的打包后输入的文件夹个别都是 dist
,devServe.static
配置项指定要提供的动态文件目录也是 dist
。所以,咱们自然而然会认为,此时webpack
开启的本地服务器拜访的内容就是 dist
文件夹外面的内容。
因而,咱们会得出谬误的论断:devServe.static
的作用就是,设置 webpack
开启的本地服务器时,拜访的目录。
然而,咱们能够看看上文的 dev.config.js,咱们设置打包后输入的文件夹名称是 dist
,devServe.static
设置的目录是 static
。如果依照咱们上文谬误的了解,因为两个文件夹设置不同,此时咱们服务器应该是404
或者空白页面才对,然而咱们仍旧能够跑起咱们的服务。
这阐明 devServe.static
的作用,并不是设置 webpack
开启的本地服务器时,拜访打包输入文件夹的目录。
正确理解
剖析
咱们持续看 learn-08 这个案例(static
文件夹外面寄存了 logo.png
图片)。
咱们之前想在 js
外面援用相干图片,咱们个别会这么做:
// index.js
const img = new Image();
img.src = require('Your image path');
咱们个别是将图片 依据相对路径 require
进来,此时图片相当于是一个模块(Module
),因而这样图片会通过 webpack
编译打包(增加 hash
或者转成base64
),最初写入到咱们设置的最终目录(output.path
)。
然而当咱们设置了:
devServer: {
static: {directory: path.join(__dirname, 'static'),
}
}
开启本地服务器后,会有这一句提醒:
Content not from webpack is served from ‘your path/static’ directory
首先,这阐明咱们设置的 static
这个目录,是不会通过 webpack
解决打包的,所以在这个文件夹外面的资源,是不会被 webpack
解析编译的,因而它也不会加上 hash
或转成base64
。
咱们再来看看 learn-08 的 index.js
是如何应用 static
里的资源的:
// index.js
loadImage('./logo.png').then(img => {console.log('I am from index.js');
img.width = 120;
document.querySelector('#js_content .img_content').append(img);
});
咱们会看到,咱们是间接应用 ./
的形式引入图片,阐明 webpack
开启的本地服务器,会将咱们设置的 static
的目录内容 映射到根目录 下。
用过
vue-cli
的同学应该能很好领会到,这其实就是vue-cli
外面public
文件夹的性能
咱们能够用以下形式拜访设置的 devServer.static.directory
文件夹里的内容:
- 个别状况下
devServer.static.directory
会被映射到根目录,所以咱们用http://[devServer.host]:[devServer.port]/[devServer.static.directory]
拜访 - 如果想扭转拜访的门路,能够减少
devServer.static.publicPath
配置。此时能够用http://[devServer.host]:[devServer.port]/[devServer.static.publicPath]/[devServer.static.directory]
拜访
总结
通过下面的剖析解说,咱们能够得出对 devServer.static
正确的了解应该是:
- 它是设置一个寄存,不通过
webpack
编译的动态资源目录(咱们能够例如图片,第三方资源等),所以它不会被加上hash
或者被转成base64
;它是一个目录 - 开启
webpack
本地服务器时,它个别会被映射到咱们的我的项目的根目录下(能够通过devServe.static.publicPath
批改拜访目录) - 因为它不通过
webpack
编译打包,所以,咱们最初个别会用copy-webpack-plugin
,将devServer.static.directory
复制到output.path
根目录下 - 它的性能就很像是
vue-cli
外面的public
文件夹,咱们开发的时候,能够通过./
或者../
拜访到那个资源(具体看目录关系)
外围
好,通过上面对开发环境配置跟 devServer
的解说,咱们能够晓得:
- 开发环境配置所有从简,所以
img
、js
等资源会间接映射在根目录下(css
被插入到<head />
里了) - 开发环境
webpack
开启本地服务器后,也会将devServer.static.directory
映射在根目录下
所以运行开发环境配置后,咱们的构造目录大抵如下:
dist
├── ecj-cli-b6fa8.png
├── index-c466b.js
├── index.html
└── logo.png
配置因人而异,最重要的是,咱们配置完开发环境,生产环境后,对编译打包输入内容,目录,脑海中有一个很好地构造意识,这是十分重要的。
这个目录构造也请大家牢记,前面的文章会用到
咱们能够通过以下办法查看开发环境的构造目录:
devServer.devMiddleware.writeToDisk: true
http://[devServer.host]:[devServer.port]/webpack-dev-server
- 谷歌浏览器
F12 -> Sources
最初
- 本篇文章学习了开发环境如何配置,下篇文章将会解说配置生产环境前一些筹备,让后续咱们更好的学习生产环境配置
- 感兴趣的同学,能够关注一下这个 👉 专栏
- 文章波及到的案例曾经上传到 github,真的欢送
star
或fork
学习
最初的最初,如果大家感觉文章有帮忙到,创作不易,还请大家多点赞转发;如果有异同点,欢送评论探讨。