UNPKG

5.72 kBJavaScriptView Raw
1/**
2 * Common webpack configuration
3 */
4const MiniHtmlWebpackPlugin = require('mini-html-webpack-plugin');
5const ProgressBarPlugin = require('progress-bar-webpack-plugin');
6const MiniCssExtractPlugin = require('mini-css-extract-plugin');
7const VirtualModulesPlugin = require('webpack-virtual-modules');
8const webpack = require('webpack');
9const { getPkg, fromCwd } = require('quickenv');
10
11const getVirtualFiles = require('./helpers/getVirtualFiles.js');
12const getEntrypoints = require('./helpers/getEntrypoints.js');
13const getHTMLTemplate = require('./helpers/getHTMLTemplate.js');
14const loaders = require('./helpers/loaders.js');
15const MambaFixesPlugin = require('./plugins/MambaFixesPlugin.js');
16const {
17 isOfModuleType,
18 transpileIgnoreBaseCondition,
19} = require('./helpers/depTranspiling.js');
20const {
21 BUNDLE_NAME,
22 IS_POS,
23 IS_BROWSER,
24 IS_DEV,
25 IS_PROD,
26 NODE_ENV,
27 APP_ENV,
28 ADD_MAMBA_SIMULATOR,
29} = require('./helpers/consts.js');
30
31const PKG = getPkg();
32
33module.exports = {
34 mode: IS_PROD ? 'production' : 'development',
35 cache: true,
36 target: 'web',
37 node: false,
38 context: fromCwd('src'),
39 entry: getEntrypoints(),
40 output: {
41 path: fromCwd('dist', BUNDLE_NAME),
42 publicPath: './',
43 filename: '[name].[hash:5].js',
44 chunkFilename: '[name].[hash:5].js',
45 },
46 resolve: {
47 /** Do not resolve symlinks */
48 symlinks: false,
49 enforceExtension: false,
50 mainFields: ['svelte', 'esnext', 'jsnext:main', 'module', 'main'],
51 extensions: ['.js', '.json', '.pcss', '.css', '.html', '.htmlx', '.svelte'],
52 /** Make webpack also resolve modules from './src' */
53 modules: [fromCwd('src'), 'node_modules'],
54 alias: {
55 page: fromCwd('node_modules', 'page'),
56 'core-js': fromCwd('node_modules', 'core-js'),
57 '@mamba/pos': fromCwd('node_modules', '@mamba', 'pos'),
58 },
59 },
60 module: {
61 rules: [
62 /**
63 * ! App modules
64 * */
65 {
66 test: /\.(htmlx?|svelte)$/,
67 include: [fromCwd('src')],
68 exclude: [/node_modules/],
69 use: [loaders.babelEsNext, loaders.svelte, loaders.eslint],
70 },
71 {
72 test: /\.js$/,
73 include: [fromCwd('src')],
74 use: [loaders.babelEsNext, loaders.eslint],
75 },
76 /**
77 * ! Dependency modules
78 * */
79 /** On dependencies svelte files, run svelte compiler and babel */
80 {
81 test: /\.(htmlx?|svelte)$/,
82 include: [/node_modules/],
83 /** When developing, parse linked packages svelte dependencies */
84 use: [loaders.babelEsNext, loaders.svelte],
85 },
86 /** Transpile .mjs dependencies as well */
87 {
88 test: /\.mjs$/,
89 include: [/node_modules/],
90 exclude: [/core-js/],
91 use: [loaders.babelEsNext],
92 },
93 /**
94 * * Run app COMMONJS dependencies through babel with module: 'commonjs'.
95 * @babel/preset-env inserts es6 import if we don't pass "module: 'commonjs'",
96 * resulting in mixed es6 and commonjs code.
97 * */
98 {
99 test: {
100 ...transpileIgnoreBaseCondition,
101 and: [isOfModuleType('cjs')],
102 },
103 use: [loaders.babelCJS],
104 },
105 /** Run app ES6 dependencies through babel with { modules: false } */
106 {
107 test: {
108 ...transpileIgnoreBaseCondition,
109 and: [isOfModuleType('es')],
110 },
111 use: [loaders.babelEsNext],
112 },
113 /**
114 * ! Generic files
115 */
116 {
117 test: /\.(css|pcss)$/,
118 /** When importing from a style file, let's
119 * use package.json's 'style' field before
120 * the actual 'main' one
121 * */
122 resolve: { mainFields: ['style', 'main'] },
123 use: [
124 loaders.extractCss,
125 loaders.css,
126 loaders.postcss,
127 loaders.resolveUrl,
128 ],
129 },
130 /** Handle font imports */
131 { test: /\.(eot|woff2?|otf|ttf)$/, use: [loaders.fonts] },
132 /** Handle image imports */
133 { test: /\.(gif|jpe?g|png|ico|svg)$/, use: [loaders.images] },
134 ],
135 },
136 plugins: [
137 /** If no real 'src/index.js' present, use the default virtual one */
138 new VirtualModulesPlugin(getVirtualFiles()),
139 /** Prepend the Function.prototype.bind() polyfill webpack's runtime code */
140 new MambaFixesPlugin(),
141 new ProgressBarPlugin(),
142 new MiniCssExtractPlugin({
143 filename: 'style.css',
144 chunkFilename: '[name].[hash:5].css',
145 }),
146 new MiniHtmlWebpackPlugin({
147 context: { title: 'Mamba Application' },
148 template: getHTMLTemplate,
149 }),
150 new webpack.DefinePlugin({
151 __NODE_ENV__: JSON.stringify(NODE_ENV),
152 __APP_ENV__: JSON.stringify(APP_ENV),
153 __PROD__: IS_PROD,
154 __TEST__: NODE_ENV === 'test',
155 __DEV__: IS_DEV,
156 __POS__: IS_POS,
157 __SIMULATOR__: ADD_MAMBA_SIMULATOR,
158 __BROWSER__: IS_BROWSER,
159 __MANIFEST__: JSON.stringify({
160 name: PKG.name,
161 description: PKG.description,
162 version: PKG.version,
163 ...PKG.mamba,
164 }),
165 }),
166 ].filter(Boolean),
167 /** Minimal useful output log */
168 stats: {
169 modules: false,
170 chunks: false,
171 colors: true,
172 children: false,
173 },
174 optimization: {
175 namedChunks: true,
176 namedModules: true,
177 /** Create a separate chunk for webpack runtime */
178 runtimeChunk: { name: 'runtime' },
179 splitChunks: {
180 chunks: 'all',
181 minSize: 0,
182 minChunks: 1,
183 cacheGroups: {
184 vendors: false,
185 libs: {
186 test: /[\\/]node_modules[\\/]/,
187 priority: -10,
188 },
189 /** Chunk that contains used polyfills */
190 polyfills: {
191 test: /core-js/,
192 name: 'polyfills',
193 priority: 10,
194 },
195 },
196 },
197 },
198};