Home Articles

使用webpack提供公共静态文件

Asked
Viewed 229 times
3

我很难按照自己的意愿配置webpack . 我在 localhost:8080 上运行我的开发服务器,并希望通过 localhost:8080/static/js/bundle.js 提供我的应用程序,这就是我用这个webpack.config.js文件得到的所有我已经附加了我想要提供 dist/static 中的其他文件作为静态文件,所以 localhost:8080/static/css/style.css 将为此 dist/static/css/style.css 文件提供服务 .

这可能是我在配置文件中做的错误,我不熟悉webpack,所以我不知道我是否提出问题,以便你能理解 .

我的目录树是:

client
  -- /dist
    -- /templates
      -- /admin
        -- index.html
    -- /static
      -- /css
        -- style.css
      -- /js
  -- /node_modules
  -- /src
  -- /test
  -- package.json
  -- webpack.config.json

webpack.config.js

var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

var plugins = [
    new webpack.ProvidePlugin({
        'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
    }),
    new ExtractTextPlugin('app.css', {
        allChunks: true
    }),
    new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development')
    })
];

var cssLoader = {};

if(process.env.NODE_ENV == 'production'){
    plugins.push(
        new webpack.optimize.UglifyJsPlugin()
    );

    cssLoader = {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]')
    };

} else {

    cssLoader = {
        test: /\.css$/,
        loaders: [
            'style?sourceMap',
            'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]'
        ]
    }

}

module.exports = {
    entry: [
        'react-hot-loader/patch',
        'webpack-dev-server/client?http://localhost:8080',
        'webpack/hot/only-dev-server',
        './src/index.js'
    ],
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                loaders: ['babel']
            },
            cssLoader
        ]
    },
    resolve: {
        extensions: ['', '.js', '.jsx']
    },
    output: {
        path: __dirname + '/dist/static',
        publicPath: '/static/js',
        filename: 'bundle.js'
    },
    devServer: {
        contentBase: './dist/templates/admin',
        hot: true,
        historyApiFallback: true
    },
    plugins: plugins
};

DIST /模板/管理/ index.html的

<!DOCTYPE html>
<html>
<head>
    <title>My App</title>
    <link href="static/css/style.css" type="text/css" rel="stylesheet" />
</head>
<body>
<div id="app"></div>
<script src="static/js/bundle.js"></script>
</body>
</html>

多谢你们 :)

3 Answers

  • 6

    显然,在某种程度上它是有意义的,当你在另一台服务器上运行时,webpack-dev-server不应该被用作加载静态文件(如CSS或其他静态JS)的后端 . 当您将 contentBase 键设置为特定目录时,文档说您必须在那里制作 index.html 文件,并且您可以根据此目录提供文件 .

    如果你想从其他目录提供静态文件,你有另一台服务器与webpack-dev-server并行运行,请注意this section of the documentation .

    我做的是在 localhost:8080 上运行webpack-dev-server,在 localhost:3000 上运行我的后端服务器,我的后端服务器在 localhost:3000/ 上从它的根路径服务 admin/index.html ,并且在html文件本身中将bundle.js的导入更改为是绝对的道路 <script src="http://localhost:8080/static/js/bundle.js"></script> .

    热重新加载现在工作正常,现在我也可以删除我的webpack配置文件的 contentBase 参数 .

    Important:

    • 现在运行我们想要的webpack并使热重载确实有效,只需在运行时添加--inline,例如: webpack-dev-server --progress --colors --hot --config ./webpack.config.js --inline

    • 你也可以使用iframe模式,但我没有潜入它 .

    • 仍然有一个问题,在构建项目时我必须手动删除绝对路径,这很烦人 . 现在看看如何自动解决它 .

  • 1

    问题

    问题的根源是WebpackDevServer only serves from one folder . 您应该提供的文件夹是包含index.html的文件夹,这正是您正在执行的操作 .

    到目前为止,您只提供 ./dist/templates/admin 的内容,因此当您在其他目录中查找文件时,您会获得404.此处唯一的例外是您的软件包,因为您正在设置一个 publicPath ,它对该路由发出任何请求 /static/js 重定向到您的输出,该输出存储在内存中 .

    您需要WebpackDevServer才能从其他文件夹中提供服务 . 在您的特定情况下,当您请求路径 /static/css 时,您还需要从 ./dist/static/css 开始服务 .

    解决方案

    您需要在WebpackDevServer中设置一些中间件 . 您可以按照documentation of devServer.setup中的说明执行此操作 . 为此,我建议您使用express.static,因为您可能已经在使用Express .

    你需要要求Express:

    const express = require('express')
    

    然后,只需修改 devServer 如下:

    devServer: {
      contentBase: './dist/templates/admin',
      hot: true,
      historyApiFallback: true,
      setup (app) {
        app.use('/static/css/',
          express.static(path.join(__dirname, 'dist', 'static', 'css')));
        /* Using this commented code will break the HMR, see edit
        app.use('/static/js/',
          express.static(path.join(__dirname, 'dist', 'static', 'js')));
        */
    
        // in general
        app.use('/public/route/',
          express.static('/your/local/path'));
      }
    }
    

    这样您的开发和构建路径保持不变,WebpackDevServer在您需要的路由上提供您需要的静态文件 .

    编辑

    我刚刚发现上面的代码打破了热模块替换 . 原因是设置中的中间件正在处理 /static/js/ ,因此捆绑包是从文件系统而不是内存提供的 .

    要继续从内存中获取包,请在 output 属性中定义 publicPath ,并且不要在 devServer.setup 内的自定义中间件中处理它 .

    module.exports = {
    
      output: {
        path: ...,
        filename: ...,
        publicPath: '/static/js/'
      },
    
      devServer: {
        contentBase: './dist/templates/admin',
        hot: true,
        historyApiFallback: true,
        setup (app) {
          app.use('/static/css/',
            express.static(path.join(__dirname, 'dist', 'static', 'css')));
        }
      },
    
      // other properties: entry, module, etc.
    }
    
  • 1

    您正在端口8080上提供应用程序 . 在您的webpack配置中,我看到您设置内容基础dist / template / Admin但我没有看到该文件夹的任何位置 . 当您设置内容库时,它将从该文件夹中为Admin.html提供服务,如果您在该文件中声明了依赖项,则它将从您那里加载 . You can take a look at this seed了解更多信息 .

Related