Webpack Configuration
Webpack configuration with following features:
- Hot Reloading in Development
- Production Optimized Build
- JSX and Vue
- Babel
- Eslint
- Sane Project Structure
How To Use
Install
Install this package
npm install sm-webpack-config --save-dev
NOTE: You need to install node-sass
if you want to use sass, and compression-webpack-plugin
if you want to use gzip option.
Programmatic Usage
const smWebpack = require('sm-webpack-config');
const config = {
sourcePath: 'res',
destPath: 'static/dist',
publicUrl: '/static/dist',
sourceMap: true,
devServerPort: 3001,
appPort: 3000,
};
smWebpack.runDevServer({config});
smWebpack.runProdWebpack({config});
const webpackConfig = {
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: true
}
}),
],
};
smWebpack.runDevServer({config, webpackConfig});
smWebpack.runProdWebpack({config, webpackConfig});
CLI Usage
sm-webpack serve
sm-webpack build
sm-webpack
sm-webpack build --dev
sm-webpack build --src res/project1 --dest static/dist/project1
sm-webpack serve --dev-port 3050
Using with config
Add a sm-webpack.js
file to your project's root directory with the config for your project exported.
Or add a "sm-webpack" key to your package.json.
Eg. sm-webpack.js:
module.exports = {
sourcePath: 'res/project1',
destPath: 'static/dist/project1',
publicUrl: '/static/dist/project1',
devServer: {
port: 3001,
appPort: 3000,
},
};
sm-webpack serve
sm-webpack
Multiple projects
If you have multiple projects you can export an object with multiple confs and use the --config [keyName]
option to select project.
Eg. sm-webpack.js:
module.exports = {
project1: {
sourcePath: 'res/project1',
destPath: 'static/dist/project1',
publicUrl: '/static/dist/project1',
devServer: {
port: 3001,
appPort: 3000,
},
},
project2: {
sourcePath: 'res/project2',
destPath: 'static/dist/project2',
publicUrl: '/static/dist/project2',
devServer: {
port: 3002,
appPort: 3000,
},
},
}
sm-webpack serve --config project1
sm-webpack --config project2
Using with Gulp
You can also use it in gulp using the following gulpfile
const smWebpack = require('sm-webpack-config');
const gulp = require('gulp');
gulp.task('default', function(callback) {
smWebpack.runDevServer().then(callback);
});
gulp.task('build', function(callback) {
smWebpack.runProdWebpack().then(callback);
});
Now you can use gulp
to run dev-server and gulp build
to build for production.
Default Project Structure
-
Keep all your client side code in res
- all javascript in
js
- vue components in
components
- 3rd party scripts in
vendor
(though they should generally be installed from npm)
- css / scss in
css
- images in
img
- other assests in
assests
- eg. fonts can be kept in
assests/fonts
- directly served static assests in
public
- assests in this directory will not be compiled and copied directly to the
public
folder in dist
- this directory should be used as public root directory in your server config
index.html
as entry point (no need to include js/css, they will automatically be injected by webpack).
-
all the compiled code will be put in static/dist
-
point your static server to static
directory
-
use public path as /static
-
api endpoints should start with /api
-
Keep your server running at port 3000
-
Dev server will run at port 3001
Webpack Aliases
The following aliases are defined
{
'@': config.sourcePath,
'res': config.sourcePath,
'js': path.join(config.sourcePath, 'js'),
'assets': path.join(config.sourcePath, 'assets'),
'components': path.join(config.sourcePath, 'js', 'components'),
'css': path.join(config.sourcePath, 'css'),
'img': path.join(config.sourcePath, 'img'),
}
So you can write import Hello from 'components/Hello.vue'
from anywhere
If you want to use images in your vue templates use them as ~img/logo.png
(append a ~)
See https://github.com/vuejs/vue-loader/issues/193
Configuration Options
const config = {
sourcePath: 'res',
destPath: 'static/dist',
publicUrl: '/static/dist',
sourceMap: true,
eslint: true,
entry: {
app: 'js/index.js',
},
entryHtml: 'index.html',
library: false,
appendHash: true,
minify: false,
gzip: false,
clean: true,
quiet: true,
babel: {
envOptions: {
targets: {chrome: '61', firefox: '60', safari: '11.1'},
},
includePresets: [],
excludePresets: [],
includePlugins: [],
excludePlugins: [],
transformImports: {},
debug: false,
},
postcss: {
remBaseline: 14,
variables: {},
},
vue: {
compilerOptions: {
whitespace: 'condense',
},
},
analyzeBundle: false,
ssr: {
entry: 'js/index-server.js',
sourceMap: true,
},
cssModules: false,
devServer: {
before(app, server) {},
after(app, server) {},
host: '0.0.0.0',
port: 3001,
https: false,
open: true,
appPort: 3000,
proxy: {
'/api': 'http://localhost:<appPort>',
'/static': 'http://localhost:<appPort>',
'/uploads': 'http://localhost:<appPort>',
},
notifyOnError: true,
buildSSR: true,
},
$env_production: {
minify: true,
eslint: false,
},
$env_development: {
eslint: true,
},
};
SSR (Server Side Rendering)
sm-webpack-config
includes support for Vue SSR. Everything should work if you set the config.ssr
option. Building will give bundles for both server side and client side.
Default bundle file names are as given by vue.
Server Bundle: vue-ssr-server-bundle.json
Client Manifest: vue-ssr-client-manifest.json
You'll need to use createBundleRenderer
from vue-server-renderer
for SSR. For more details see Vue SSR docs
Running Dev Server With SSR
Running dev server with ssr support is a bit tricky. You'll need to use your own server and koa middleware provided by sm-webpack-config
to set it up. koaDevServer
fires a vue-ssr
event with {serverBundle, clientManifest}
as parameters whenever a new ssr bundle is ready.
Here's a quick example
const Koa = require('koa');
const {createBundleRenderer} = require('vue-server-renderer');
const {koaDevServer} = require('sm-webpack-config');
const app = new Koa();
const template = fs.readFileSync('./res/index.html', 'utf-8');
function createRenderer(bundle, clientManifest) {
const options = {
clientManifest,
template,
runInNewContext: false,
};
return createBundleRenderer(bundle, options);
}
const buildConfig = {
entry: {
app: 'js/index-client.js',
},
devServer: {
port: 3002,
appPort: 3000,
},
ssr: {
entry: 'js/index-server.js',
sourceMap: true,
},
};
const devServer = koaDevServer({
config: buildConfig,
});
let renderer;
devServer.on('vue-ssr', ({serverBundle, clientManifest}) => {
renderer = createRenderer(serverBundle, clientManifest);
});
const renderToString = (...args) => {
if (!renderer) return 'Waiting to generate renderer...';
return renderer.renderToString(...args);
};
app.use(devServer.middleware());
app.use(async (ctx, next) => {
const ssrContext = {url: ctx.url};
ctx.body = await renderToString(ssrContext);
});
app.listen(3000);
For a more complete setup with production + dev server ssr, see SSR Example
Rollup
sm-webpack-config
also includes rollup. You can use it as:
const smWebpack = require('sm-webpack-config');
const config = {
entry: 'src/index.js',
dest: 'dest/index.js',
library: 'vutils',
libraryFormat: 'es',
minify: false,
sourceMap: false,
$env_production: {
minify: true,
},
$env_development: {
minify: false,
},
};
smWebpack.runRollup({config}).then(() => {
console.log("Done!");
});
Rollup Configuration Options
const config = {
entry: 'src/index.js',
dest: 'dist/index.js',
library: 'lib',
libraryFormat: 'umd',
minify: false,
sourceMap: false,
};