1 | const fs = require('fs')
|
2 | const webpack = require('webpack')
|
3 | const nodeExternals = require('webpack-node-externals')
|
4 | const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin')
|
5 | const config = require('./paths')
|
6 | const path = require('path')
|
7 | const babelPreset = require('../babel')
|
8 |
|
9 | // This is the Webpack configuration.
|
10 | // It is focused on developer experience and fast rebuilds.
|
11 | module.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 | clearConsole: options.env === 'development',
|
131 | }),
|
132 | // The NoEmitOnErrorsPlugin plugin prevents Webpack
|
133 | // from printing out compile time stats to the console.
|
134 | new webpack.NoEmitOnErrorsPlugin()
|
135 | ]
|
136 | }
|
137 | }
|