webpack中的path、publicPath和contentBase

14,329 阅读4分钟

本文主要总结一下webpack里面关于path、publicPath和contentBase的区别及用法。

  • output里面的path表示的是output目录对应的一个绝对路径。
  • output里面的publicPath表示的是打包生成的index.html文件里面引用资源的前缀
  • devServer里面的publicPath表示的是打包生成的静态文件所在的位置(若是devServer里面的publicPath没有设置,则会认为是output里面设置的publicPath的值)
  • devServer里面的contentBase表示的是告诉服务器从哪里提供内容。(只有想提供静态文件时才需要)

基本配置

目录结构

- src
  - index.css
  - index.js
- index.html  
- package.json
- webpack.config.js

webpack.config.js

const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {
    entry: './src/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist') 
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.css/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ]
            }
        ]
    },
    devtool: 'source-map',
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './src/index.html'
        }),
        new MiniCssExtractPlugin({
            filename: 'style.css'
        }),
        new webpack.HotModuleReplacementPlugin()
    ]
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>webpack-dev-server</title>
</head>
<body>
  <div id="app">aaa</div>
</body>
</html>

index.css

#app {
    color: red;
}

index.js

import './index.css'

package.json

在里面添加两条命令

"scripts": {
    ...,
    "build": "webpack",
    "dev": "webpack-dev-server --open chrome"
}

下面通过例子来了解一下path、publicPath和contentBase的区别吧。

output

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。

path

output里面的path很好理解,指的就是output目录对应的一个绝对路径。

output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist') // 输出目录对应的绝对路径
},

运行npm run build 命令打包文件,可以看到打包之后的文件都输出到了dist文件夹。

publicPath

output中的publicPath常用于在生产环境。它会为所有的资源指定一个基础路径。设置了publicPath后,会为资源添加一个前缀。 看例子: 将output中的配置改为:

output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'), // 输出目录对应的绝对路径
        publicPath: '/outputdist/'
},

运行npm run dev 命令 可以看到命令行显示如下信息:

  • 访问http://localhost:8080/ 结果显示:
  • 访问http://localhost:8080/outputdist/ 结果显示:

由上面两张图可以看出,在output里面设置了publicPath以后,若是devServer里面没有设置publicPath,则使用webpack-dev-server 在进行打包时生成的静态文件所在的位置以及index.html文件里面引用资源的前缀都是output.publicPath里面设置的值

devServer

publicPath

添加devServer的配置:

devServer: {
    hot: true,
    publicPath: '/dist/'
}

然后运行npm run dev, 命令行显示如下信息:

  • 访问http://localhost:8080/结果显示:
  • 访问http://localhost:8080/dist/ 结果显示:
    控制台会提示找不到相关文件:

可以看出devServer里面的publicPath表示的是打包生成的静态文件所在的位置。并且它的优先级是最高的。而publicPath代表的是index.html文件里面引用资源的前缀

contentBase

添加contentBase的配置:

devServer: {
        contentBase: './aaa', // 不设置的话,默认是当前执行的目录,一般是项目根目录。会在项目根目录查找index.html文件。
        hot: true,
        publicPath: '/dist/'
},

然后运行npm run dev, 命令行显示如下信息:

可以看出contentBase指的是不是由webpack打包生成的静态文件

  • 访问http://localhost:8080/结果显示:
    因为我们并没有aaa目录,所以根本找不到。而前面的设置没有设置contentBase,会使用contentBase的默认值,默认就是根目录。访问http://localhost:8080/,由于在根目录下没有找到index.html文件,因此会显示根目录下的资源文件。
  • 访问http://localhost:8080/dist/,显示的结果为:
    可见,contentBase与打包生成的静态文件所在的位置和index.html里面引入资源的前缀是没有影响的。

更改一下配置:

devServer: {
        contentBase: './src', // 不设置的话,默认是当前执行的目录,一般是项目根目录。会在项目根目录查找index.html文件。
        hot: true,
        publicPath: '/dist/'
},

将contentBase设置为src目录,src目录里面是有index.html文件的。看一下执行结果。 运行npm run dev, 访问http://localhost:8080/结果显示:

可以看出,访问的是我们在本地编写的index.html文件。