A friend recommended I learn Webpack because of how much time it saves him with hot-reloading while encoding. He gave me a basic webpack.config.js file and it worked fine for a single entry point.
This week a client asked me to encode a prototype site and I'd like to augment my webpack.config to allow for multiple entry points. Unfortunately, I'm predominantly a designer so most of webpack config's syntax is Greek to me, and i can't seem to find the answer online.
Here's what I was hoping for:
Project Root
|
+-- node_modules
|
+-- dist
| |
| +-- css
| | |
| | +-- custom.css (global styles)
| | +-- report1.css (styles for report 1 only)
| | +-- report2.css (styles for report 2 only)
| | +-- vendor.css (bootstrap, font-awesome, vendors, etc.)
| |
| +-- fonts
| | |
| | +-- fontawesome-webfont.eot
| | +-- fontawesome-webfont.svg
| | +-- fontawesome-webfont.ttf
| | +-- fontawesome-webfont.woff
| | +-- fontawesome-webfont.woff2
| |
| +-- js
| | |
| | +-- common.js (global scripts)
| | +-- report1.js (scripts for report 1 only)
| | +-- report2.js (scripts for report 2 only)
| | +-- vendor.js (bootstrap, jquery, etc.)
| |
| +-- index.html (listing page for reports)
| +-- report1.html
| +-- report2.html
|
+-- src
| |
| +-- fonts
| | |
| | +-- fontawesome-webfont.eot
| | +-- fontawesome-webfont.svg
| | +-- fontawesome-webfont.ttf
| | +-- fontawesome-webfont.woff
| | +-- fontawesome-webfont.woff2
| |
| +-- js
| | |
| | +-- common.js (global scripts incl. bootstrap, jquery import)
| | +-- report1.js (scripts for report 1 only)
| | +-- report2.js (scripts for report 2 only)
| |
| +-- scss
| |
| +-- bootstrap.scss (overrides and link to node_module import)
| +-- common.scss (common styles)
| +-- font-awesome.css (@font-face imports)
|
+-- index.html
+-- package.json
+-- report1.html
+-- report2.html
+-- weppack.config.js
Naturally, I'd like to be able to have a lot of reports, not just the two.
Here's the webpack.config.js file which i hacked from my friend's skeleton and other StackOverflow answers.
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: {
common: './src/js/common.js',
report1: './src/js/report1.js',
report2: './src/js/report2.js',
custom: './src/scss/custom.scss',
vendor: [
'./src/scss/bootstrap.scss',
'./src/scss/font-awesome.css'
],
},
output: {
path: path.resolve(__dirname, './dist'),
publicPath: '/dist/',
filename: 'js/[name].js'
},
module: {
rules: [
{
test: /\.s[ac]ss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ["css-loader","sass-loader"],
})
},
{
test: /\.css$/,
loader: 'style-loader!css-loader?sourceMap'
},
// Font Definitions
{ test: /\.svg?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=65000&mimetype=image/svg+xml&name=fonts/[name].[ext]' },
{ test: /\.woff?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=65000&mimetype=application/font-woff&name=fonts/[name].[ext]' },
{ test: /\.woff2?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=65000&mimetype=application/font-woff2&name=fonts/[name].[ext]' },
{ test: /\.[ot]tf?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=65000&mimetype=application/octet-stream&name=fonts/[name].[ext]' },
{ test: /\.eot?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?limit=65000&mimetype=application/vnd.ms-fontobject&name=fonts/[name].[ext]' }
],
},
plugins: [
new ExtractTextPlugin({
filename: "css/[name].css",
allChunks: true
}),
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
filename: "js/vendor.js",
minChunks: ({resource}) => /node_modules/.test(resource),
}),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'window.jQuery': 'jquery',
'Tether': 'tether',
'window.Tether': 'tether'
}),
new HtmlWebpackPlugin({
title: "Report 1",
inject: false,
chunks: ['report1'],
filename: 'report1.html'
}),
new HtmlWebpackPlugin({
title: "Report 2",
inject: false,
chunks: ['report2'],
filename: 'report2.html'
}),
],
devServer: {
port: process.env.PORT || 8080,
historyApiFallback: { index: "/" },
},
};
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = false;
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: true
},
output: {
comments: false
},
sourceMap: false
})
]);
}
The issues I'm having with the above are:
-
There's no hot reloading. While I can run
npm run devandnpm run build, even though it sees the update, the browser returns with "Nothing to update" (and it's probably because it's not listening to the right files in the right locations or something). -
I keep getting an empty "dist/js/custom.js" file (no biggie)
-
I'm not certain if I'm doing any of this correctly, since I'm importing bootstrap scss from the node_module and other people recommended copying it to a /src/scss/bootstrap folder.
I know this seems like a pretty specialized case -- and maybe not exactly what Webpack was made for -- but oftentimes, my clients want to see rapid iterations on prototyped sites prior to plugging in live data and moving the finalized, encoded pages to a live environment. Using SASS, live-reloading and chunking common vs. specific compiled css and js would really save me a lot of time...if i could just figure out how to fix my webpack.config.js file.
Any help would be greatly appreciated.
via Ben Coffin
No comments:
Post a Comment