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