UNPKG

4.67 kBJavaScriptView Raw
1const banner = require('@neutrinojs/banner');
2const compile = require('@neutrinojs/compile-loader');
3const copy = require('@neutrinojs/copy');
4const clean = require('@neutrinojs/clean');
5const startServer = require('@neutrinojs/start-server');
6const hot = require('@neutrinojs/hot');
7const nodeExternals = require('webpack-node-externals');
8const { optimize } = require('webpack');
9const {
10 basename, join, parse, format
11} = require('path');
12const merge = require('deepmerge');
13const {
14 omit, partialRight, pathOr, pipe
15} = require('ramda');
16
17const MODULES = join(__dirname, 'node_modules');
18const getOutputForEntry = pipe(
19 parse,
20 omit(['base']),
21 partialRight(merge, [{ ext: '.js' }]),
22 format,
23 basename
24);
25
26module.exports = (neutrino, opts = {}) => {
27 const pkg = neutrino.options.packageJson;
28 const staticDir = join(neutrino.options.source, 'static');
29 const sourceMap = pathOr(
30 pathOr(false, ['dependencies', 'source-map-support'], pkg),
31 ['devDependencies', 'source-map-support'],
32 pkg
33 );
34 const options = merge({
35 hot: true,
36 polyfills: {
37 async: true
38 },
39 targets: {
40 node: '6.10'
41 },
42 clean: opts.clean !== false && {
43 paths: [neutrino.options.output]
44 }
45 }, opts);
46
47 neutrino.use(compile, {
48 include: [neutrino.options.source, neutrino.options.tests],
49 exclude: [staticDir],
50 babel: compile.merge({
51 plugins: [
52 ...(options.polyfills.async ? [[require.resolve('fast-async'), { spec: true }]] : []),
53 require.resolve('babel-plugin-dynamic-import-node')
54 ],
55 presets: [
56 [require.resolve('babel-preset-env'), {
57 debug: neutrino.options.debug,
58 targets: options.targets,
59 modules: false,
60 useBuiltIns: true,
61 exclude: options.polyfills.async ? ['transform-regenerator', 'transform-async-to-generator'] : []
62 }]
63 ]
64 }, options.babel)
65 });
66
67 Object
68 .keys(neutrino.options.mains)
69 .forEach(key => neutrino.config.entry(key).add(neutrino.options.mains[key]));
70
71 neutrino.config
72 .when(sourceMap, () => neutrino.use(banner))
73 .performance
74 .hints(false)
75 .end()
76 .target('node')
77 .node
78 .set('__filename', false)
79 .set('__dirname', false)
80 .end()
81 .devtool('source-map')
82 .externals([nodeExternals({ whitelist: [/^webpack/] })])
83 .context(neutrino.options.root)
84 .output
85 .path(neutrino.options.output)
86 .filename('[name].js')
87 .libraryTarget('commonjs2')
88 .chunkFilename('[id].[hash:5]-[chunkhash:7].js')
89 .end()
90 .resolve
91 .modules
92 .add('node_modules')
93 .add(neutrino.options.node_modules)
94 .add(MODULES)
95 .when(__dirname.includes('neutrino-dev'), modules => {
96 // Add monorepo node_modules to webpack module resolution
97 modules.add(join(__dirname, '../../node_modules'));
98 })
99 .end()
100 .extensions
101 .merge(neutrino.options.extensions.concat('json').map(ext => `.${ext}`))
102 .end()
103 .end()
104 .resolveLoader
105 .modules
106 .add(neutrino.options.node_modules)
107 .add(MODULES)
108 .when(__dirname.includes('neutrino-dev'), modules => {
109 // Add monorepo node_modules to webpack module resolution
110 modules.add(join(__dirname, '../../node_modules'));
111 })
112 .end()
113 .end()
114 .when(neutrino.options.debug, (config) => {
115 config.merge({
116 stats: {
117 maxModules: Infinity,
118 optimizationBailout: true
119 }
120 });
121 })
122 .when(neutrino.options.command === 'start', (config) => {
123 const mainKeys = Object.keys(neutrino.options.mains);
124
125 neutrino.use(startServer, {
126 name: getOutputForEntry(neutrino.options.mains[mainKeys[0]])
127 });
128 config.when(options.hot, () => {
129 neutrino.use(hot);
130 mainKeys.forEach(key => neutrino.config.entry(key).add(`${require.resolve('webpack/hot/poll')}?1000`));
131 });
132 })
133 .when(neutrino.options.env.NODE_ENV === 'development', (config) => {
134 config.devtool('inline-sourcemap');
135 config.output.devtoolModuleFilenameTemplate('[absolute-resource-path]');
136 })
137 .when(neutrino.options.env.NODE_ENV === 'production', (config) => {
138 config
139 .plugin('module-concat')
140 .use(optimize.ModuleConcatenationPlugin);
141 })
142 .when(neutrino.options.command === 'build', (config) => {
143 config.when(options.clean, () => neutrino.use(clean, options.clean));
144 neutrino.use(copy, {
145 patterns: [{
146 context: staticDir,
147 from: '**/*',
148 to: basename(staticDir)
149 }]
150 });
151 });
152};