Created
May 30, 2019 18:19
-
-
Save dgrigg/d4811ee9bc85d31376f4cb7365abf04d to your computer and use it in GitHub Desktop.
Webpack + Twig setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const webpack = require('webpack'); | |
const CopyWebpackPlugin = require('copy-webpack-plugin'); | |
const HtmlWebpackPlugin = require('html-webpack-plugin'); | |
const CleanWebpackPlugin = require('clean-webpack-plugin'); | |
const ManifestPlugin = require('webpack-manifest-plugin'); | |
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |
const WebpackNotifierPlugin = require('webpack-notifier'); | |
const TailwindCss = require('tailwindcss'); | |
const AutoPrefixer = require('autoprefixer'); | |
const path = require('path'); | |
const fs = require('fs'); | |
const purgecss = require('@fullhuman/postcss-purgecss')({ | |
// Specify the paths to all of the template files in your project | |
content: [ | |
'./src/**/*.twig', | |
'./src/**/*.js', | |
'./node_modules/slick-carousel/slick/slick.js', | |
], | |
// Include any special characters you're using in this regular expression | |
defaultExtractor: content => content.match(/[A-Za-z0-9-_:/]+/g) || [], | |
}); | |
// create a list of twig files to generate | |
// filter out anything that starts with an underscore or is not a twig file | |
function walk(dir) { | |
let results = []; | |
const list = fs.readdirSync(dir); | |
list.forEach(file => { | |
file = `${dir}/${file}`; | |
const stat = fs.statSync(file); | |
if (stat && stat.isDirectory() && path.basename(file).indexOf('_') !== 0) { | |
/* Recurse into a subdirectory */ | |
results = results.concat(walk(file)); | |
} else if ( | |
stat && | |
!stat.isDirectory() && | |
path.extname(file) === '.twig' && | |
path.basename(file).indexOf('_') !== 0 | |
) { | |
/* Is a file */ | |
results.push(file); | |
} | |
}); | |
return results; | |
} | |
const files = walk('./src/twig'); | |
// generates html plugins to export | |
const htmlPlugins = files.map( | |
file => | |
// Create new HTMLWebpackPlugin with options | |
new HtmlWebpackPlugin({ | |
filename: file.replace('./src/twig/', '').replace('.twig', '.html'), | |
template: path.resolve(__dirname, file), | |
hash: true, | |
}) | |
); | |
module.exports = { | |
stats: { | |
entrypoints: false, | |
children: false, | |
}, | |
context: path.resolve(__dirname, 'src'), | |
entry: { | |
main: './js/main.js', | |
}, | |
output: { | |
publicPath: '/', | |
path: path.join(__dirname, './web'), | |
filename: '[name].[hash].js', | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.js$/, | |
exclude: /node_modules/, | |
use: [ | |
{ | |
loader: 'babel-loader', | |
}, | |
], | |
}, | |
{ | |
test: /\.(sa|sc|c)ss$/, | |
use: [ | |
{ | |
loader: MiniCssExtractPlugin.loader, | |
options: { | |
hmr: process.env.NODE_ENV === 'development', | |
}, | |
}, | |
'css-loader', | |
{ | |
loader: 'postcss-loader', | |
options: { | |
ident: 'postcss', | |
plugins: loader => [ | |
TailwindCss, | |
AutoPrefixer, | |
...(process.env.NODE_ENV == 'production' ? [purgecss] : []), | |
], | |
}, | |
}, | |
'sass-loader', | |
], | |
}, | |
{ | |
test: /\.(woff2?|ttf|eot|svg)(\?.*)?$/i, | |
use: 'file-loader?name=fonts/[name].[hash].[ext]', | |
}, | |
// Twig templates | |
{ | |
test: /\.twig$/, | |
use: [ | |
'raw-loader', | |
{ | |
loader: 'twig-html-loader', | |
options: { | |
data: {}, | |
}, | |
}, | |
], | |
}, | |
], | |
}, | |
plugins: [ | |
new WebpackNotifierPlugin({ alwaysNotify: true }), | |
// inject into files | |
new webpack.ProvidePlugin({ | |
jQuery: 'jquery', | |
jquery: 'jquery', | |
$: 'jquery', | |
'window.jQuery': 'jQuery', | |
}), | |
new MiniCssExtractPlugin({ | |
// Options similar to the same options in webpackOptions.output | |
// both options are optional | |
filename: '[name].[hash].css', | |
chunkFilename: '[id].css', | |
}), | |
new CopyWebpackPlugin([{ from: './assets', to: './assets' }]), | |
new CleanWebpackPlugin({ | |
protectWebpackAssets: true, | |
cleanOnceBeforeBuildPatterns: [], | |
cleanAfterEveryBuildPatterns: [ | |
'*.js', | |
'*.css', | |
'*.map', | |
'.html', | |
'!uploads/**', | |
'!assets/**', | |
], | |
}), | |
new ManifestPlugin({ | |
filter: ({ name }) => name.endsWith('.js') || name.endsWith('.css'), | |
}), | |
].concat(htmlPlugins), | |
watch: false, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment