1 | const banner = require('@neutrinojs/banner');
|
2 | const compile = require('@neutrinojs/compile-loader');
|
3 | const copy = require('@neutrinojs/copy');
|
4 | const clean = require('@neutrinojs/clean');
|
5 | const startServer = require('@neutrinojs/start-server');
|
6 | const hot = require('@neutrinojs/hot');
|
7 | const nodeExternals = require('webpack-node-externals');
|
8 | const { optimize } = require('webpack');
|
9 | const {
|
10 | basename, join, parse, format
|
11 | } = require('path');
|
12 | const merge = require('deepmerge');
|
13 | const {
|
14 | omit, partialRight, pathOr, pipe
|
15 | } = require('ramda');
|
16 |
|
17 | const MODULES = join(__dirname, 'node_modules');
|
18 | const getOutputForEntry = pipe(
|
19 | parse,
|
20 | omit(['base']),
|
21 | partialRight(merge, [{ ext: '.js' }]),
|
22 | format,
|
23 | basename
|
24 | );
|
25 |
|
26 | module.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 |
|
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 |
|
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 | };
|