const fs = require('fs') const path = require('path') const webpack = require('webpack') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const StylablePlugin = require('stylable-integration/webpack-plugin') const production = process.env.NODE_ENV === 'production' const settings = require('./scripts/settings.js') const devServer = settings.devServer const basePath = path.join(__dirname) const cssModulesPath = path.resolve(__dirname, '05-react-css-modules') const stylablePath = path.resolve(__dirname, '09-stylable') const deCSSPath = path.resolve(__dirname, '13-decss') let cssModulesLoaders = [ 'decss-loader/react', 'css-loader?modules&importLoaders=1&localIdentName=[name]_[local]_[hash:base64:3]', 'postcss-loader' ] let deCSSPathLoaders = [ 'style-loader', 'decss-loader/react', 'css-loader?modules&importLoaders=1&localIdentName=[name]_[local]_[hash:base64:3]', ] if (production) { cssModulesLoaders = ExtractTextPlugin.extract([ 'css-loader?modules&importLoaders=1&localIdentName=[name]_[local]_[hash:base64:3]', 'postcss-loader' ]) } function isDirectory (dir) { return fs.lstatSync(dir).isDirectory() } const projectPaths = fs.readdirSync(basePath).filter((projdDir) => { let isProject = /^[0-9]{2}-.+/ if (isProject.test(projdDir)) { return isDirectory(path.join(basePath, projdDir)) } }) // HMR using react-hot-loader 3 & webpack-hot-middleware const reactHotLoader = 'react-hot-loader/patch' const webpackHotMiddleware = 'webpack-hot-middleware/client?reload=1' const babelPolyfill = 'babel-polyfill' // core-js ? const hotEntries = [ babelPolyfill, reactHotLoader, webpackHotMiddleware ] const webpackEntries = projectPaths.reduce((allEntreis, currPath) => { if (fs.existsSync(path.join(basePath, currPath, './button/entry.js'))) { allEntreis[currPath.substr(3) + '/button'] = [ ...hotEntries, path.join(basePath, currPath, './button/entry.js') ] } if (fs.existsSync(path.join(basePath, currPath, './workshop/entry.js'))) { allEntreis[currPath.substr(3) + '/workshop'] = [ ...hotEntries, path.join(basePath, currPath, './workshop/entry.js') ] } if (fs.existsSync(path.join(basePath, currPath, './solution/entry.js'))) { allEntreis[currPath.substr(3) + '/solution'] = [ ...hotEntries, path.join(basePath, currPath, 'solution/entry.js') ] } return allEntreis }, {}) let htmlPlugins = Object.keys(webpackEntries).reduce((acc, cur, idx, arr) => { acc.push(new HtmlWebpackPlugin({ inject: true, template: cur.indexOf('button') !== -1 ? 'templates/server.ejs' : 'templates/plain.ejs', title: cur, filename: cur + '/index.html', chunks: [ cur ] })) return acc }, []) const webpackPlugins = [ ...htmlPlugins, new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(), new StylablePlugin({ injectBundleCss: true, nsDelimiter: '_' }) ] if (production) { webpackPlugins.push(new ExtractTextPlugin('[name].css')) } module.exports = { devServer: devServer, devtool: 'cheap-module-eval-source-map', entry: webpackEntries, plugins: webpackPlugins, output: { path: path.join(__dirname), filename: '[name].js', chunkFilename: '[id].chunk.js', publicPath: '/' }, resolve: { alias: { CSS3: path.resolve(__dirname, 'public/css') } }, module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: [ 'react-hot-loader/webpack', 'babel-loader?cacheDirectory=true' ] }, { test: /\.css/, include: [ deCSSPath ], use: deCSSPathLoaders }, { test: /\.s?css$/, include: [ cssModulesPath ], use: cssModulesLoaders }, StylablePlugin.rule(), { test: /\.(png|jpg|gif|svg)$/, include: [ stylablePath ], use: [ { loader: 'url-loader', options: { limit: 8192 } } ] }, { test: /\.css$/, exclude: [ deCSSPath, stylablePath, cssModulesPath ], use: [ 'style-loader', 'css-loader' ], }, { test: /\.(jpe?g|png|gif|svg)$/i, exclude: [ stylablePath ], use: [ 'file-loader?name=[path][name].[hash].[ext]' ] }, { test: /\.json$/, use: 'json-loader' } ] } }