UNPKG

4.74 kBJavaScriptView Raw
1/* eslint-disable global-require */
2const _ = require('lodash');
3const path = require('path');
4const merge = require('webpack-merge');
5
6const {getConfig} = require('./default');
7const {getOptimizationConfig} = require('./optimization');
8const {getPlugins} = require('./plugins');
9const {getLoaders} = require('./loaders');
10const getNodeConfig = require('./node');
11
12function getDevTool(config) {
13 if (config.isSSR && config.ssr.sourceMap) return '#cheap-source-map';
14 if (!config.sourceMap) return false;
15 if (config.isProduction) return '#source-map';
16 return '#eval-source-map';
17}
18
19function getFileName(config) {
20 if (config.library || !config.appendHash) return '[name].js';
21 // webpack does not support base62 encoding in contenthash yet
22 if (config.isProduction) return 'js/[name].[contenthash:7].js';
23 return 'js/[name].js';
24}
25
26/**
27 * @param options it is {env, config, webpackConfig}
28 * env can be developement or production
29 * config gets merged into our default config
30 * webpackConfig gets merged into final webpack config
31 */
32function getWebpackConfig(options = {}) {
33 const env = options.env || process.env.NODE_ENV || 'development';
34
35 const config = getConfig(options.config, env);
36 options.config._final = config;
37 const webpackConfig = options.webpackConfig || {};
38
39 const isProduction = config.isProduction;
40
41 // correct NODE_ENV is important for vue-loader to correctly minify files
42 process.env.NODE_ENV = isProduction ? 'production' : 'development';
43
44 const cwd = config.cwd;
45
46 config.sourcePath = path.join(cwd, config.sourcePath);
47 config.destPath = path.join(cwd, config.destPath);
48
49 const entry = {};
50 _.forEach(config.entry, (value, key) => {
51 if (!Array.isArray(value)) {
52 value = [value];
53 }
54 entry[key] = value.map(val => path.join(config.sourcePath, val));
55 });
56
57 const baseConfig = {
58 target: 'web',
59 mode: isProduction ? 'production' : 'development',
60 context: cwd,
61 entry,
62 output: {
63 path: config.destPath,
64 publicPath: config.publicUrl,
65 filename: getFileName(config),
66 chunkFilename: getFileName(config),
67 },
68 resolve: {
69 extensions: ['.wasm', '.mjs', '.js', '.mjsx', '.jsx', '.vue', '.json'],
70 modules: [
71 path.join(cwd, 'node_modules'),
72 path.join(__dirname, '../node_modules'),
73 ],
74 alias: {
75 '@': config.sourcePath,
76 res: config.sourcePath,
77 js: path.join(config.sourcePath, 'js'),
78 assets: path.join(config.sourcePath, 'assets'),
79 components: path.join(config.sourcePath, 'js', 'components'),
80 css: path.join(config.sourcePath, 'css'),
81 img: path.join(config.sourcePath, 'img'),
82 },
83 },
84 resolveLoader: {
85 modules: [
86 path.join(cwd, 'node_modules'),
87 path.join(__dirname, '../node_modules'),
88 ],
89 },
90 module: {
91 // don't parse these modules to speed up things
92 noParse: /node_modules(.*)\/(firepad|jquery)\//,
93 rules: getLoaders(config),
94 },
95 node: getNodeConfig(config),
96 optimization: getOptimizationConfig(config),
97 plugins: getPlugins(config),
98 devtool: getDevTool(config),
99 };
100
101 if (config.isSSR) {
102 const nodeExternals = require('webpack-node-externals');
103
104 // entry should be app's server entry file
105 baseConfig.entry = path.join(config.sourcePath, config.ssr.entry);
106
107 // output filename for server bundle
108 baseConfig.output.filename = 'server-bundle.js';
109
110 // This allows webpack to handle dynamic imports in a Node-appropriate
111 // fashion, and also tells `vue-loader` to emit server-oriented code when
112 // compiling Vue components.
113 baseConfig.target = 'node';
114
115 // This tells the server bundle to use Node-style exports
116 baseConfig.output.libraryTarget = 'commonjs2';
117
118 // https://webpack.js.org/configuration/externals/#function
119 // https://github.com/liady/webpack-node-externals
120 // Externalize app dependencies. This makes the server build much faster
121 // and generates a smaller bundle file.
122 baseConfig.externals = nodeExternals({
123 // do not externalize dependencies that need to be processed by webpack.
124 // you can add more file types here e.g. raw *.vue files
125 // you should also whitelist deps that modifies `global` (e.g. polyfills)
126 whitelist: [
127 /\.(postcss|pcss|sass|scss|less|css|vue|jsx)$/,
128 /\?vue&type=style/,
129 ],
130 });
131 }
132
133 if (config.library) {
134 baseConfig.output.libraryTarget = config.libraryFormat || 'umd';
135 baseConfig.output.umdNamedDefine = true;
136 baseConfig.output.library = config.library === true ? 'Lib' : config.library;
137 }
138
139 if (!isProduction) {
140 // for working with hmr in web workers
141 // https://github.com/webpack/webpack/issues/6642
142 baseConfig.output.globalObject = 'this';
143
144 // disable performace hints
145 baseConfig.performance = {hints: false};
146 }
147
148 return merge(baseConfig, webpackConfig);
149}
150
151module.exports = {
152 getWebpackConfig,
153};