UNPKG

5.29 kBJavaScriptView Raw
1const fs = require('fs')
2const webpack = require('webpack')
3const nodeExternals = require('webpack-node-externals')
4const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
5const config = require('./paths')
6const path = require('path')
7const babelPreset = require('../babel')
8
9// This is the Webpack configuration.
10// It is focused on developer experience and fast rebuilds.
11module.exports = (options) => {
12 const babelRcPath = path.resolve('.babelrc')
13 const hasBabelRc = fs.existsSync(babelRcPath)
14 const mainBabelOptions = {
15 babelrc: true,
16 cacheDirectory: true,
17 presets: []
18 }
19
20 if (hasBabelRc) {
21 console.log('> Using .babelrc defined in your app root')
22 } else {
23 mainBabelOptions.presets.push(require.resolve('../babel'))
24 }
25
26 return {
27 // Webpack can target multiple environments such as `node`,
28 // `browser`, and even `electron`. Since Backpack is focused on Node,
29 // we set the default target accordingly.
30 target: 'node',
31 // The benefit of Webpack over just using babel-cli or babel-node
32 // command is sourcemap support. Although it slows down compilation,
33 // it makes debugging dramatically easier.
34 devtool: 'source-map',
35 // Webpack allows you to define externals - modules that should not be
36 // bundled. When bundling with Webpack for the backend - you usually
37 // don't want to bundle its node_modules dependencies. This creates an externals
38 // function that ignores node_modules when bundling in Webpack.
39 // @see https://github.com/liady/webpack-node-externals
40 externals: nodeExternals({
41 whitelist: [
42 /\.(eot|woff|woff2|ttf|otf)$/,
43 /\.(svg|png|jpg|jpeg|gif|ico|webm)$/,
44 /\.(mp4|mp3|ogg|swf|webp)$/,
45 /\.(css|scss|sass|less|styl)$/,
46 ]
47 }),
48 // As of Webpack 2 beta, Webpack provides performance hints.
49 // Since we are not targeting a browser, bundle size is not relevant.
50 // Additionally, the performance hints clutter up our nice error messages.
51 performance: {
52 hints: false
53 },
54 // Since we are wrapping our own webpack config, we need to properly resolve
55 // Backpack's and the given user's node_modules without conflict.
56 resolve: {
57 extensions: ['.js', '.json'],
58 modules: [config.userNodeModulesPath, path.resolve(__dirname, '../node_modules')]
59 },
60 resolveLoader: {
61 modules: [config.userNodeModulesPath, path.resolve(__dirname, '../node_modules')]
62 },
63 node: {
64 __filename: true,
65 __dirname: true
66 },
67 entry: {
68 main: [
69 `${config.serverSrcPath}/index.js`
70 ],
71 },
72 // This sets the default output file path, name, and compile target
73 // module type. Since we are focused on Node.js, the libraryTarget
74 // is set to CommonJS2
75 output: {
76 path: config.serverBuildPath,
77 filename: '[name].js',
78 sourceMapFilename: '[name].map',
79 publicPath: config.publicPath,
80 libraryTarget: 'commonjs2'
81 },
82 // Define a few default Webpack loaders. Notice the use of the new
83 // Webpack 2 configuration: module.rules instead of module.loaders
84 module: {
85 rules: [
86 // This is the development configuration.
87 // It is focused on developer experience and fast rebuilds.
88 {
89 test: /\.json$/,
90 loader: 'json-loader'
91 },
92 // Process JS with Babel (transpiles ES6 code into ES5 code).
93 {
94 test: /\.(js|jsx)$/,
95 loader: 'babel-loader',
96 exclude: [
97 /node_modules/,
98 config.buildPath
99 ],
100 options: mainBabelOptions
101 }
102 ]
103 },
104 plugins: [
105 // We define some sensible Webpack flags. One for the Node environment,
106 // and one for dev / production. These become global variables. Note if
107 // you use something like eslint or standard in your editor, you will
108 // want to configure __DEV__ as a global variable accordingly.
109 new webpack.DefinePlugin({
110 'process.env.NODE_ENV': JSON.stringify(options.env),
111 '__DEV__': options.env === 'development'
112 }),
113 // In order to provide sourcemaps, we automagically insert this at the
114 // top of each file using the BannerPlugin.
115 new webpack.BannerPlugin({
116 raw: true,
117 entryOnly: false,
118 banner: `require('${
119 // Is source-map-support installed as project dependency, or linked?
120 ( require.resolve('source-map-support').indexOf(process.cwd()) === 0 )
121 // If it's resolvable from the project root, it's a project dependency.
122 ? 'source-map-support/register'
123 // It's not under the project, it's linked via lerna.
124 : require.resolve('source-map-support/register')
125 }')`
126 }),
127 // The FriendlyErrorsWebpackPlugin (when combined with source-maps)
128 // gives Backpack its human-readable error messages.
129 new FriendlyErrorsWebpackPlugin(),
130 // This plugin is awkwardly named. Use to be called NoErrorsPlugin.
131 // It does not actually swallow errors. Instead, it just prevents
132 // Webpack from printing out compile time stats to the console.
133 // @todo new webpack.NoEmitOnErrorsPlugin()
134 new webpack.NoErrorsPlugin()
135 ]
136 }
137}