I have a standard ReactJS project. Using webpack, my build
outputs a dist/
like the following:
- js/
- css/
- assets/
- images/
- fonts/
- index.html
In order to deploy in an idempotent fashion, using Cloudfront, I'd need dist/
to look like:
- index.html
- 1ae7aa42-2979-4aff-aa54-d4700ddccd8d/
- assets/
- images/
- fonts/
- js/
- css/
I've tried this myself and got some-way there with:
'use strict';
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const uuid = require('uuid/v4')();
module.exports = {
entry: [
`${__dirname}/src/js/app.js`,
`${__dirname}/src/scss/index.scss`,
],
output: {
path: `${__dirname}/dist/`,
filename: uuid + '/js/[name].js',
publicPath: '/',
},
resolve: {
modules: [ 'node_modules', `${__dirname}/src/js` ],
},
watchOptions: {
poll: true,
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader',
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [ 'css-loader', 'sass-loader' ],
}),
},
{ test: /\.(eot|svg|ttf|woff|woff2)$/,
use: [
{loader: 'file-loader', options: {
name: '/[name].[ext]',
publicPath: '/' + uuid + '/assets/fonts/',
emitFile: false
}}
]
},
plugins: [
new ExtractTextPlugin({ filename: uuid + '/css/[name].css' }),
new CopyWebpackPlugin([{ from: './src/assets', to: uuid + "/assets/"}]),
new HtmlWebpackPlugin({
title: 'App',
template: 'index.ejs',
inject: 'body',
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
'process.env.SENTRY_KEY': JSON.stringify(process.env.SENTRY_KEY),
'process.env.API_URL': JSON.stringify(process.env.API_URL),
'process.env.GRAPHQL_URL': JSON.stringify(process.env.GRAPHQL_URL),
'process.env.SOCKET_URL': JSON.stringify(process.env.SOCKET_URL),
}),
],
};