首页 文章

Express:在子路由上提供 Webpack 包

提问于
浏览
0

我已经构建了一个带有 Express 后端和 React 前端的 Web 应用程序。

每当向 Express 服务器发出请求时,它首先检查 URL 是否与任何后端路由匹配,如果不匹配,它会将使用 Webpack 生成的 React 包发送到客户端(其中 URL 路由由 React Router 处理)。

这适用于所有基本路线。但是,只要向子路径发出请求(e.g. /foo/bar),Express 就会正确地提供index.html,但似乎找到一个目录foo来提供bundle.js,这在这种情况下是不受欢迎的行为,并导致错误,因为那里找不到文件。对于 JS 文件,可以使用相对路径来修复此问题,但是 Webpack 处理的图像仍然存在问题。

有人知道解决方案吗?

server.js:

server.listen(port, () => {
    // set up API routes
    server.use('/api/auth', require(...));
    server.use('/api/users', require(...));

    // serve public files (JavaScript bundle, images, etc.)
    server.use(express.static(path.join(__dirname, '../client', 'public')));

    // serve index.html on all other routes
    server.get('*', (request, response) => {
        response.sendFile(path.join(__dirname, '../client', 'public', 'index.html'));
    });
});

index.html:

<!DOCTYPE html>

<html>
    <head>
        ...
    </head>

    <body>
        <div id="root"></div>
        <script src="/client-bundle.js"></script>
    </body>
</html>

React 组件中的图像导入示例:

import someIcon from '../public/img/someIcon.svg';
...
<img src={someIcon}>

Webpack 配置:

module.exports = {
    entry: './client/index.jsx',
    output: {
        path: path.join(__dirname, 'client/public'),
        filename: 'bundle.js'
    },
    module: {
        rules: [
            { test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/ },
            { test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] },
            { test: /\.(jpe?g|png|gif|svg)$/, loader: 'file-loader?name=img/[name].[ext]' }
        ]
    },
    resolve: {
        extensions: ['.js', '.jsx']
    }
};

我的文件结构:

/app
    /client
        /components
            /SomeComponent.jsx
        /index.jsx
        /public
            /index.html
            /bundle.js
            /img
                /someIcon.svg
    /server
        /server.js

1 回答

  • 1

    您可以在 webpack 配置中设置服务器的公共路径。如果你设置了公共路径,那么 webpack 将用你公开的公共路径替换图像和其他文件的路径。

    output: {
            path: path.join(__dirname, 'client/public'),
            publicPath: "http://localhost:3000/",
            filename: 'bundle.js'
        },
    

    同样在您的文件加载器中,您正在设置name=img/[name].[ext]

    因此,通过上述配置,您的图像路径将被替换为

    http://localhost:3000/img/someIcon.svg

相关问题