I struggle to get webpack configured as I want it to be. I run my dev-server on localhost:8080 and want to serve my app through localhost:8080/static/js/bundle.js and that is what I get with this webpack.config.js file I've attached below. in my file structure i've alse attached I want to serve also the other files located in dist/static as static files, so localhost:8080/static/css/style.css will be serving this dist/static/css/style.css file for example.
it is probably something wrong i did in the config file, and i'm not that familiar with webpack so i don't know if im asking the question so you can understand.
My directory tree is:
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/templates/admin/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>
thanks guys :)
Content Base. The webpack-dev-server will serve the files in the current directory, unless you configure a specific content base. Using this config webpack-dev-server will serve the static files in your public folder. It'll watch your source files for changes and when changes are made the bundle will be recompiled.
publicPath specifies the virtual directory in web server from where bundled file, app. js is going to get served up from. Keep in mind, the word server when using publicPath can be either webpack-dev-server or express server or other server that you can use with webpack. for example module.
devServer.clientAllows to set log level in the browser, e.g. before reloading, before an error or when Hot Module Replacement is enabled. webpack.config.js module.
webpack-dev-server is Webpack's officially supported CLI-based tool for starting a static server for your assets. While you don't need any CLI tools to use Webpack, webpack-dev-server gives you a single command that starts a static server with built-in live reload.
The origin of the problem is that the WebpackDevServer only serves from one folder. The folder that you should be serving from is the folder containing the index.html, which is what you're correctly doing.
So far you're serving only the content of ./dist/templates/admin
, therefore when you look for files in other directories you get a 404. The only exception here is your bundle, because you're setting a publicPath
that makes any request to the route /static/js
be redirected to your output, which is stored in memory.
You would need the WebpackDevServer to be able to serve from other folders. In your specific case, you need to serve also from ./dist/static/css
when you request the path /static/css
.
You need to set some middlewares in your WebpackDevServer. You can do so as described in the documentation of devServer.setup
. To do so, I suggest you use express.static
, as you're probably already using Express.
You need to require Express:
const express = require('express')
And then, just modify the devServer
as follows:
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'));
}
}
This way your devs and build paths stay the same, and the WebpackDevServer serves the static files you need, at the routes you need.
I just discovered that the code above breaks the Hot Module Replacement. The reason is that the middleware in the setup is handling /static/js/
, so the bundle is served from the file system instead of memory.
To keep fetching the bundle from memory define a publicPath
in the output
property, and don't handle it from a custom middleware inside 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.
}
You are serving the app on port 8080. In your webpack config I see that you set content base dist/template/Admin but I don't see that folder any where. When you set content base it will serve Admin.html from that folder and if you have declared dependencies in that file it will load from you. You can take a look at this seed to learn more about it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With