UNPKG

6.23 kBJavaScriptView Raw
1const path = require('path');
2const fs = require('fs')
3const webpack = require('webpack');
4const autoprefixer = require('autoprefixer');
5const ExtractTextPlugin = require("extract-text-webpack-plugin");
6const ManifestPlugin = require('webpack-manifest-plugin');
7const workboxPlugin = require('workbox-webpack-plugin');
8const common = require('./webpack-common.js');
9const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
10
11const LINC_DIR = common.LINC_DIR;
12const PROJECT_DIR = common.PROJECT_DIR;
13const DIST_DIR = path.resolve(PROJECT_DIR, 'dist');
14
15const srcDir = common.srcDir;
16
17const createConfig = (options) => {
18 options = options || {}
19
20 const url_loader_config = {
21 exclude: [
22 /\.html$/,
23 /\.(js|jsx)$/,
24 /\.css$/,
25 /\.json$/,
26 /\.svg$/,
27 /\.woff$/,
28 /\.woff2$/,
29 /\.eot$/,
30 /\.ttf$/,
31 ],
32 loader: 'url-loader',
33 query: {
34 limit: 10,
35 name: '_assets/media/[name].[hash:8].[ext]'
36 }
37 }
38
39 const extractPlugin = ExtractTextPlugin.extract({
40 fallback: {
41 loader: 'style-loader',
42 options: {
43 sourceMap: true,
44 hmr: false,
45 }
46 },
47 use:[
48 {
49 loader: 'css-loader',
50 options: {
51 sourceMap: true,
52 modules: common.packageJson.linc.cssModules || false,
53 importLoaders: 1,
54 minimize: true,
55 localIdentName: "[name]__[local]___[hash:base64:5]"
56 }
57 },
58 {
59 loader: 'postcss-loader',
60 options: {
61 // Necessary for external CSS imports to work
62 // https://github.com/facebookincubator/create-react-app/issues/2677
63 ident: 'postcss',
64 plugins: () => [
65 require('postcss-flexbugs-fixes'),
66 autoprefixer({
67 browsers: [
68 '>1%',
69 'last 4 versions',
70 'Firefox ESR',
71 'not ie < 9', // React doesn't support IE8 anyway
72 ],
73 flexbox: 'no-2009',
74 }),
75 ],
76 },
77 },
78 ]
79 })
80
81 const css_loader = {
82 test: /\.(css)$/,
83 loader: extractPlugin,
84 }
85
86 const babel_options = options.babel || { presets: [], plugins: [] }
87 babel_options.presets.push(
88 ['env', {
89 "targets": {
90 "browsers": ["> 1%", "last 2 versions"]
91 },
92 modules: false
93 }]
94 )
95 babel_options.presets.push('stage-1')
96
97 let plugins = [
98 common.definePlugin,
99 new webpack.optimize.OccurrenceOrderPlugin(),
100 new webpack.LoaderOptionsPlugin({
101 minimize: true,
102 debug: false
103 }),
104 new webpack.optimize.CommonsChunkPlugin({
105 name: 'vendor',
106 minChunks: (module) => (
107 // return true if module is from node_modules
108 typeof module.userRequest === 'string' &&
109 module.userRequest.indexOf('/node_modules/') >= 0
110 )
111 }),
112 new webpack.optimize.CommonsChunkPlugin({
113 name: ['vendor', 'manifest']
114 }),
115 // extract css as text from js
116 new ExtractTextPlugin({
117 filename: '_assets/css/[name].[chunkhash:8].css'
118 }),
119 new ManifestPlugin({
120 fileName: '../lib/asset-manifest.json'
121 }),
122 new webpack.ProvidePlugin({
123 React: 'react',
124 }),
125 new workboxPlugin({
126 globDirectory: path.resolve(DIST_DIR, 'static'),
127 globPatterns: ['_assets/**/*.{html,js,css,png,svg}'],
128 swDest: path.join(DIST_DIR, 'lib', 'includes', 'serviceworker.js'),
129 dontCacheBustUrlsMatching: /\.\w{8}\./,
130 }),
131 new webpack.optimize.UglifyJsPlugin({
132 beautify: false,
133 sourceMap: true,
134 mangle: {
135 screw_ie8: true,
136 keep_fnames: true
137 },
138 compress: {
139 screw_ie8: true
140 },
141 comments: false
142 }),
143 new BundleAnalyzerPlugin({
144 analyzerMode: 'static',
145 reportFilename: '../bundle-report.html',
146 defaultSizes: 'gzip',
147 openAnalyzer: false,
148 generateStatsFile: false,
149 statsFilename: '../webpack-stats.json',
150 statsOptions: null,
151 logLevel: 'error'
152 })
153 ]
154
155 plugins = plugins.concat(options.plugins.map((pluginOptions) => common.createPlugin(pluginOptions)))
156
157 const entry = {
158 'main': [path.resolve(DIST_DIR, 'client.js')],
159 }
160 const deferFile = path.resolve(srcDir, 'defer.js')
161 if(fs.existsSync(deferFile)) {
162 entry.defer = [deferFile]
163 }
164
165 return {
166 entry,
167
168 resolve: {
169 alias: {
170 'linc-config-js': path.resolve(PROJECT_DIR, srcDir, 'linc.config.js')
171 },
172
173 modules: [srcDir, "node_modules", path.resolve(PROJECT_DIR, "node_modules")],
174 extensions: [".js", ".json", ".jsx"]
175 },
176 resolveLoader: {
177 modules: ['node_modules', path.resolve(LINC_DIR, 'node_modules')]
178 },
179 output: {
180 // The build folder.
181 path: path.resolve(DIST_DIR, 'static'),
182 // Generated JS file names (with nested folders).
183 // There will be one main bundle, and one file per asynchronous chunk.
184 // We don't currently advertise code splitting but Webpack supports it.
185 filename: '_assets/js/[name].[chunkhash:8].js',
186 chunkFilename: '_assets/js/[name].[chunkhash:8].chunk.js',
187 // We inferred the "public path" (such as / or /my-project) from homepage.
188 publicPath: common.publicPath
189 },
190
191 module: {
192 rules: [
193 url_loader_config,
194 {
195 test: /\.svg$/,
196 loader: 'svg-url-loader',
197 query: {
198 limit: 10,
199 name: '_assets/media/[name].[hash:8].[ext]'
200 }
201 },
202 { enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
203 {
204 test: /\.js$/,
205 loader: 'babel-loader',
206 exclude: /node_modules/,
207 options: babel_options
208 },
209 css_loader,
210 {
211 test: /\.(woff|woff2|eot|ttf)$/,
212 loader: 'file-loader',
213 options: {
214 name: '_assets/fonts/[name].[hash:8].[ext]'
215 }
216 }
217 ]
218 },
219 plugins,
220
221 stats: {
222 children: false,
223 },
224
225 // https://webpack.js.org/configuration/devtool/
226 // 'eval' | 'cheap-eval-source-map' | 'cheap-module-eval-source-map' | 'eval-source-map'
227 devtool: 'source-map'
228 };
229}
230
231module.exports = createConfig
\No newline at end of file