1 | const webpack = require("webpack");
|
2 | const process = require("process");
|
3 | const path = require("path");
|
4 | const fs = require("fs");
|
5 |
|
6 | const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
7 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
8 | const ManifestPlugin = require("webpack-manifest-plugin");
|
9 |
|
10 | exports.webpackConfig = function webpackConfig(publisherName, currentDirectory, opts = {}) {
|
11 | const PUBLIC_PATH = `/${publisherName}/assets/`;
|
12 | const OUTPUT_DIRECTORY = currentDirectory + `/public/${PUBLIC_PATH}`;
|
13 |
|
14 | const BABEL_PRESET = {
|
15 | loader: "babel-loader",
|
16 | options: {
|
17 | presets: ["es2015-tree-shaking", "react"],
|
18 | plugins: [
|
19 | ["react-css-modules", {
|
20 | webpackHotModuleReloading: process.env.NODE_ENV != "production",
|
21 | generateScopedName: "[name]__[local]__[hash:base64:5]"
|
22 | }]
|
23 | ],
|
24 | }
|
25 | };
|
26 |
|
27 | const config =
|
28 | process.env.NODE_ENV == "production"
|
29 | ? {
|
30 | outputFileName: suffix => `[name]-[hash:20].${suffix}`,
|
31 | sassLoader: [MiniCssExtractPlugin.loader, {
|
32 | loader: "css-loader",
|
33 | }, {
|
34 | loader: "sass-loader",
|
35 | }],
|
36 | cssModuleLoader: [MiniCssExtractPlugin.loader, {
|
37 | loader: "css-loader", options: {modules: true, importLoaders: 1, localIdentName: "[name]__[local]__[hash:base64:5]"}
|
38 | },{
|
39 | loader: "postcss-loader",
|
40 | options: {
|
41 | ident: "postcss",
|
42 | sourceMap: true,
|
43 | plugins: (loader) => [
|
44 | require("precss")(),
|
45 | require("autoprefixer")
|
46 | ]
|
47 | }
|
48 | }],
|
49 | cssFile: `[name]-[contenthash:20].css`,
|
50 | compressCSSPlugins: [new OptimizeCssAssetsPlugin({
|
51 | cssProcessorOptions: { safe: true }
|
52 | })],
|
53 | outputPublicPath: PUBLIC_PATH,
|
54 | sourceMapType: 'source-map'
|
55 | }
|
56 | : {
|
57 | outputFileName: suffix => `[name].${suffix}`,
|
58 | sassLoader: [{loader: "style-loader"}, {loader: "css-loader", options: {sourceMap: true}}, {loader: "sass-loader", options: {sourceMap: true}}],
|
59 | cssModuleLoader: [
|
60 | {loader: "style-loader"},
|
61 | {loader: "css-loader", options: {sourceMap: true, modules: true, importLoaders: 1, localIdentName: "[name]__[local]__[hash:base64:5]"}},
|
62 | {
|
63 | loader: "postcss-loader",
|
64 | options: {
|
65 | ident: "postcss",
|
66 | sourceMap: true,
|
67 | plugins: (loader) => [
|
68 | require("precss")(),
|
69 | require("autoprefixer")
|
70 | ]
|
71 | }
|
72 | }
|
73 | ],
|
74 | cssFile: `[name].css`,
|
75 | compressCSSPlugins: [],
|
76 | outputPublicPath: "http://localhost:8080" + PUBLIC_PATH,
|
77 | sourceMapType: 'eval-source-map'
|
78 | };
|
79 |
|
80 | const entryFiles = Object.assign({
|
81 | app: "./app/client/app.js",
|
82 | serviceWorkerHelper: "./app/client/serviceWorkerHelper.sjs"
|
83 | }, opts.entryFiles);
|
84 |
|
85 | if(fs.existsSync("./app/client/polyfill.js")) {
|
86 | entryFiles["polyfill"] = "./app/client/polyfill.js";
|
87 | }
|
88 |
|
89 | return {
|
90 | entry: entryFiles,
|
91 | mode: process.env.NODE_ENV == 'production' ? 'production' : 'development',
|
92 | output: {
|
93 | path: OUTPUT_DIRECTORY,
|
94 | filename: config.outputFileName("js"),
|
95 | publicPath: config.outputPublicPath
|
96 | },
|
97 | module: {
|
98 | rules: [
|
99 | { test: /\.jsx?$/, exclude: /node_modules/, use: BABEL_PRESET },
|
100 | { test: /\.jsx?$/, include: /node_modules\/@quintype\/framework/, use: BABEL_PRESET },
|
101 | { test: /\.jsx?$/, include: /node_modules\/@quintype\/components\/store/, use: BABEL_PRESET },
|
102 | { test: /\.(sass|scss)$/, use: config.sassLoader },
|
103 | { test: /\.module.css$/, use: config.cssModuleLoader },
|
104 | { test: /\.m.css$/, use: config.cssModuleLoader },
|
105 | {
|
106 | test: /\.(jpe?g|gif|png|svg|woff|woff2|eot|ttf|wav|mp3|ico|mp4)$/,
|
107 | loader: "file-loader",
|
108 | query: {
|
109 | context: "./app/assets",
|
110 | name: config.outputFileName("[ext]")
|
111 | }
|
112 | }
|
113 | ]
|
114 | },
|
115 | plugins: [
|
116 | new webpack.EnvironmentPlugin({ NODE_ENV: "development" }),
|
117 | new MiniCssExtractPlugin({filename: config.cssFile}),
|
118 | new ManifestPlugin({
|
119 | map(asset) {
|
120 | return Object.assign(asset, {
|
121 | path: asset.path.replace(config.outputPublicPath, PUBLIC_PATH),
|
122 | });
|
123 | },
|
124 | fileName: "../../../asset-manifest.json",
|
125 | publicPath: PUBLIC_PATH,
|
126 | writeToFileEmit: true
|
127 | })
|
128 | ].concat(config.compressCSSPlugins),
|
129 |
|
130 | devServer: {
|
131 | headers: { "Access-Control-Allow-Origin": "*" }
|
132 | },
|
133 | devtool: config.sourceMapType
|
134 | };
|
135 | };
|