使用webpack提供公共静态文件

Dim*_*urg 9 webpack webpack-dev-server

我很难按照自己的意愿配置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
Run Code Online (Sandbox Code Playgroud)

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
};
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

多谢你们 :)

Dan*_*ina 11

问题

问题的根源是WebpackDevServer 仅从一个文件夹提供服务.您应该提供的文件夹是包含index.html的文件夹,这正是您正在执行的操作.

到目前为止,你只提供内容./dist/templates/admin,因此当你在其他目录中查找文件时,你得到的是404.这里唯一的例外是你的捆绑,因为你设置了一个publicPath使得对路由的任何请求/static/js被重定向到你的输出,存储在内存中.

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


解

您需要在WebpackDevServer中设置一些中间件.你可以按照文档中的devServer.setup描述这样做.为此,我建议您使用express.static,因为您可能已经在使用Express.

你需要要求Express:

const express = require('express')
Run Code Online (Sandbox Code Playgroud)

然后,只需修改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'));
  }
}
Run Code Online (Sandbox Code Playgroud)

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

编辑

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

要继续从内存中获取bundle,请publicPath在output属性中定义a ,并且不要从内部的自定义中间件处理它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.
}
Run Code Online (Sandbox Code Playgroud)