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