首页 > 解决方案 > 无法从浏览器访问 Webpack 开发服务器 JS 和 CSS 包 (404)(使用 Twig)

问题描述

目标

在具有实时重载(不是 HMR)功能的 docker 设置中使用 webpack 开发服务器。

问题

不提供 CSS 和 JS 捆绑包。在浏览器开发人员控制台中,CSS 和 JS(以及其他资产)都出现 404 错误,并且仅显示纯 HTML。

截图开发者控制台

描述

我正在开发一个 dockerized PHP 项目。有一个通过网络连接的 NGINX、mariadb 和 PHP 容器。项目文件被挂载到 PHP 容器中,在 NGINX 容器上我打开了端口 80 和 443。为了澄清,相关片段来自docker-compose.yaml

version: '3.8'

services:
  nginx:
    container_name: ${COMPOSE_PROJECT_NAME}_${APP_ENVIRONMENT}_nginx
    build: nginx
    ports:
      - "80:80"
      - "443:443"
      - "8080:443"
    volumes:
      - volume-data:/var/www/${APP_DOMAIN}/current
      - ./nginx/templates:/etc/nginx/templates
    environment:
      NGINX_HOST: "${APP_DOMAIN}"
    healthcheck:
      test: "curl -f -k -s https://localhost/healthcheck || exit 1"
      interval: 15s
      timeout: 3s
    working_dir: /etc/nginx
    restart: always
    networks:
      - backend_net

  php:
    container_name: ${COMPOSE_PROJECT_NAME}_${APP_ENVIRONMENT}_php
    build:
      context: ./php
      target: php
    volumes:
      - volume-data:/var/www/${APP_DOMAIN}/current
    env_file:
      - sendgrid_api_key.env
      - session_symmetric_key.env
      - mariadb.env
    environment:
      HOST_PATH_TO_PROJECT: "${PWD}/.."
      APP_ENVIRONMENT: "${APP_ENVIRONMENT}"
    healthcheck:
      test: "curl -f -k -s https://nginx/ping || exit 1"
      interval: 15s
      timeout: 3s
    working_dir: /var/www/${APP_DOMAIN}/current
    restart: always
    networks:
      - backend_net

{...}


volumes:
  volume-mariadb:
  volume-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: $PWD/..

networks:
  backend_net:
    driver: bridge

在 webpack 配置内部,我正在合并 webpack 配置,具体取决于productiondevelopment模式。

const {merge} = require('webpack-merge');

//depending on the command here common configs get merged with prod or dev configs

const commonConfig = require('./webpack.common');

module.exports = ({env}) => {
    const envConfig = require(`./webpack.${env}.js`);

    return merge(commonConfig, envConfig);
};

package.jsoni 定义--env.env=dev中,它将通用配置与开发配置合并。启动 webpack 开发服务器的整个脚本如下所示:

"test": "webpack-dev-server --config frontend/build-utils/webpack.config.js --mode development --env.env=dev --watch"

常见的webpack.config看起来是这样的:

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {

    entry: {
        scripts: './frontend/index.js',
        vendor: './frontend/vendor.js',
    },
    target: 'web',
    output: {
        path: path.resolve('public/assets'),
        filename: "[name].bundle.js",
        libraryTarget: 'umd',
        globalObject: 'this',
        // umdNamedDefine: true,
        library: '[name]'
    },
    module: {
        rules: [
            {
                // Apply rule for .sass, .scss or .css files
                test: /\.(sa|sc|c)ss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        // This loader resolves url() and @imports inside CSS
                        loader: "css-loader",
                        options: {
                            url: false,
                            sourceMap: true,
                        }

                    },
                    {
                        loader: 'resolve-url-loader',
                    },
                    {
                        // transform SASS to standard CSS
                        loader: "sass-loader",
                        options: {
                            implementation: require("sass"),
                            sourceMap: true,
                        }
                    },
                ]
            },
            {
                test: /\.(js)$/,
                exclude: /node_modules/,
                use: ['babel-loader']
            },
        ]
    },

    resolve: {
        extensions: ['*', '.js']
    },

    plugins: [
        new CopyWebpackPlugin({
                patterns: [
                    {
                        from: 'frontend/images/', to: 'images/'
                    }              
            
                ],
            },
        ),
        new MiniCssExtractPlugin({
            filename: 'styles.css',
        }),
    ]
};

webpack dev config

const path = require('path');

module.exports = {
    mode: 'development',
    devtool: 'eval',
    devServer: {
        publicPath: path.resolve('public/assets'),
        contentBase: path.resolve('public'),
        // port: 3000,
        host: '0.0.0.0',
        https: true,
        watchOptions: {
            ignored: /node_modules/,
            aggregateTimeout: 500, // delay before reloading
            poll: 1000 // enable polling since fsevents are not supported in docker
        },
    },
};

项目的文件夹结构:

root/
 ├── frontend
 ...
 ├── public/
      ├── index.php 
      └──  assets/
           ├── style.bundle.css
           ├── scripts.bundle.js
           └── images/
 ├── src
     └── Layout/
          └── Templates/
              └── page-layout.twig

最后是我如何在树枝模板中调用资产的示例:

<link rel="stylesheet" href="/assets/styles.css">

webpack dev config我尝试将路径设置contentBaseindex.phptwig 模板的路径,以及从 PHP 中使用的路径。但是 CSS 和 JS 仍然缺失。也试过没有path.resolve

当我在没有开发服务器的情况下运行 webpack 时"dev": "webpack --config frontend/build-utils/webpack.config.js --env.env=dev",资产会被正确捆绑和复制,我可以访问它们。

标签: dockernginxwebpackwebpack-dev-server

解决方案


推荐阅读