长期以来,一直都比较迷惑,不知道publicPath属性的作用,最近抽空,花了点时间研究了下,参考了几篇文档,自己测试了几遍,最后得出了以下几点心得,如有不对,欢迎佐证。
1.当手动创建html时,也就是当我们的工程中,存在一个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="root">
</div>
<script type="text/javascript" src="main.js"></script></body>
</html>
此时webpack配置为
let config = {
entry: {
main: ['./app/App.js']
},
output: {
path: path.resolve(__dirname, 'dist/assets'),
filename: '[name].js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ["@babel/preset-env", "@babel/preset-react"]
}
}
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: path.join(__dirname, "dist"),//devServer的根目录
hot: true,
port: 9000,
host: 'localhost'
}
}
package.json里面的命令如下
"scripts": {
"dev": "node_modules/.bin/webpack-dev-server",
"build": "node_modules/.bin/webpack --config webpack.config.js",
"watch": "webpack --watch"
},
当我们在命令行里面运营npm run dev,在浏览器里面输入http://localhost:9000/ 可以看到我们的index.html里面已经有内容呈现,并且实现了热替换,本次demo是基于react开发的,旨在讲解publicPath的作用,react不作更多解释。
此时假如我们运营npm run build,可以看到在我们的工程目录dist下面的assets里面已经生成了我们想要的main.js,但是通过在浏览器里面访问该html文件,可以看到里面界面是空白的。
原因主要是webpack-dev-server打包生成的文件是写进了内存里面,浏览器控制台中的sources 面板下面可以看到。对应的路径根据根目录(此时的根目录是由devServer的contentBase属性设定的)而定,文件名是按照output定义的filename命名的,这个时候publicPath没有设置,即采用默认值“/”,固打包后在http://localhost:9000/main.js可以看到该文件,但并没有写进磁盘,所以此时通过webpack-dev-server打包可以正常访问内容
2.当我们调整下publicPath的的值,
publicPath: '/dist/assets/'
我们先执行npm run build ,此时在assets目录下面生成了main.js,这时将index.html引用路径改为src="/dist/assets/main.js"
再运营npm run dev ,发现访问http://localhost:9000还是可以正常访问页面内容,这个时候将index.html的引用路径改为src="/assets/main.js",发现还是可以正常访问,此时如果将assets下面的main.js移除,则无法再正常访问了,再次证明了webpack-dev-server打包生成的文件是写进内存里面的,并且当在内存中找不到相关的依赖文件时,会在磁盘目录下去找,当找到时,则正常引入,找不到时则报错
3.使用webpackHTMLplugin自动创建文件,
plugins里面添加
new HtmlWebpackPlugin({
template: './src/index.html'
}),
运行npm run dev时,可以看到再用原来的路径已经访问不到页面了,改为http://localhost:9000/dist/assets/index.html又能正常访问了,但是磁盘目录下面依旧没有生成该文件,证明使用了webpackHTMLplugin之后还是在内存里面开辟了一片空间去存放打包文件
假设此时再次改变打包之后html文件的存放地址,往assets的上一层目录存放
new HtmlWebpackPlugin({
template: './src/index.html',
filename: '../index.html'
}),
此时再npm run dev ,发现不管怎么样都访问不到index.html了,说明使用HtmlWebpackPlugin时,在devServer模式下,是不能任意指定index.html的存放地址的,要么就手动在对应位置添加一个index.html