Created
October 1, 2020 10:49
-
-
Save Flcwl/46442f774ef193a5f6cbc96167575875 to your computer and use it in GitHub Desktop.
Webpack Encore + Sass + MiniCSSExtractPlugin + PurgeCSS + OptimizeCss + Babel + Typescript
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
/* eslint-disable no-useless-escape */ | |
const Encore = require('@symfony/webpack-encore'); | |
const TerserPlugin = require('terser-webpack-plugin'); | |
const CircularDependencyPlugin = require('circular-dependency-plugin'); | |
const HtmlCriticalWebpackPlugin = require('html-critical-webpack-plugin'); | |
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); | |
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | |
const PurgeCssPlugin = require('purgecss-webpack-plugin'); | |
const WebpackBar = require('webpackbar'); | |
const path = require('path'); | |
const glob = require('glob-all'); | |
const cssWhitelist = require('./purge-css-whitelist'); | |
const sassOptions = { | |
includePaths: ['node_modules', './resources/assets/scss/'], | |
}; | |
if (!Encore.isRuntimeEnvironmentConfigured()) { | |
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev'); | |
} | |
Encore.addPlugin(new WebpackBar()); | |
if (!Encore.isProduction()) { | |
Encore.configureFilenames({ | |
js: '[name].js', | |
css: '[name].css', | |
images: 'images/[name].[ext]', | |
fonts: 'fonts/[name].[ext]', | |
}); | |
} else { | |
Encore.enablePostCssLoader(); | |
} | |
if (!Encore.isProduction()) { | |
Encore.addPlugin( | |
new CircularDependencyPlugin({ | |
// exclude detection of files based on a RegExp | |
exclude: /a\.js|node_modules/, | |
// add errors to webpack instead of warnings | |
failOnError: true, | |
// set the current working directory for displaying module paths | |
cwd: process.cwd(), | |
}), | |
); | |
} | |
// Uncomment only when generating static site for above the fold CSS (critical CSS). | |
// if (!Encore.isProduction()) { | |
// Encore.addPlugin( | |
// new HtmlCriticalWebpackPlugin({ | |
// base: path.resolve(__dirname, 'public'), | |
// src: 'static_home.html', | |
// dest: 'optimized_home.html', | |
// inline: true, | |
// minify: true, | |
// extract: true, | |
// width: 375, | |
// height: 565, | |
// penthouse: { | |
// blockJSRequests: false, | |
// timeout: 99999, | |
// }, | |
// }), | |
// ); | |
// } | |
Encore.setOutputPath('public/assets/') // directory where compiled assets will be stored | |
.setPublicPath('/assets'); // public path used by the web server to access the output path | |
if (Encore.isProduction()) { | |
Encore.cleanupOutputBeforeBuild(); | |
} | |
Encore.copyFiles({ | |
from: './resources/assets/images', | |
to: 'images/[path][name].[ext]', | |
pattern: /\.(png|jpg|jpeg|gif|svg)/, | |
}); | |
if (Encore.isProduction()) { | |
Encore.copyFiles({ | |
from: './resources/assets/images', | |
to: 'images/[path][name]', | |
pattern: '/(logopng)/', | |
}); | |
} | |
// Encore.enableSassLoader(options => { | |
// options.includePaths = sassOptions.includePaths; | |
// | |
// if (!Encore.isProduction()) { | |
// options.minimize = false; | |
// } else { | |
// options.minimize = true; | |
// } | |
// }); | |
Encore.addLoader({ | |
test: /\.scss$/, | |
use: [ | |
{ | |
loader: MiniCssExtractPlugin.loader, | |
options: { | |
// you can specify a publicPath here | |
// by default it uses publicPath in webpackOptions.output | |
publicPath: '../', | |
hmr: process.env.NODE_ENV === 'development', | |
}, | |
}, | |
'css-loader', | |
'sass-loader', | |
], | |
}); | |
Encore.addPlugin( | |
new MiniCssExtractPlugin({ | |
filename: Encore.isProduction() ? '[name].[contenthash].css' : '[name].css', | |
}), | |
); | |
if (Encore.isProduction()) { | |
Encore.addPlugin( | |
new OptimizeCSSAssetsPlugin({ | |
assetNameRegExp: /\.(c|s[ac])ss$/, | |
cssProcessorPluginOptions: { | |
preset: [ | |
'default', | |
{ | |
discardComments: { | |
removeAll: true, // remove any comments? | |
}, | |
}, | |
], | |
}, | |
canPrint: true, | |
}), | |
); | |
} | |
Encore.addPlugin( | |
new TerserPlugin({ | |
terserOptions: { | |
sourceMap: !Encore.isProduction(), | |
cache: !Encore.isProduction(), | |
parallel: true, | |
output: { | |
// comments: false, | |
}, | |
}, | |
}), | |
); | |
if(Encore.isProduction()) { | |
Encore.addPlugin( | |
new PurgeCssPlugin({ | |
// folders: ['resources/views/**/*', 'resources/assets/scss/'], | |
paths: glob.sync([path.join(__dirname, 'resources/views/**/*/*.blade.php')]), | |
whitelist: cssWhitelist, | |
whitelistPatterns: [ | |
/icon$/, | |
/primary$/, | |
/info$/, | |
/success$/, | |
/danger$/, | |
/swiper\-w+/, | |
/slide$/, | |
/popover\-\w+/, | |
/tooltip\-\w+/, | |
/lb\-\w+/, | |
/ui\-\w+/, | |
], | |
}), | |
); | |
} | |
Encore.configureOptimizeCssPlugin().enableSourceMaps(!Encore.isProduction()); | |
Encore.configureBabel( | |
babelConfig => { | |
// add additional presets (preset-env is added by default) | |
babelConfig.presets.push('@babel/preset-flow'); | |
// IE11/Edge requires below plugins | |
babelConfig.plugins.push('@babel/plugin-transform-spread'); | |
babelConfig.plugins.push('@babel/plugin-transform-exponentiation-operator'); | |
// no plugins are added by default, but you can add some | |
// babelConfig.plugins.push('styled-jsx/babel'); | |
// if (Encore.isProduction()) { | |
// babelConfig.plugins.push("transform-remove-console"); | |
// } | |
}, | |
{ | |
// node_modules is not processed through Babel by default | |
// but you can whitelist specific modules to process | |
includeNodeModules: [ | |
'jquery', | |
'jquery-ui', | |
'jquery-lazy', | |
'swiper', | |
'es-cookies', | |
'select2', | |
'mdb', | |
'bootstrap', | |
'urijs', | |
'dom7', | |
'cleave.js', | |
], | |
useBuiltIns: 'usage', | |
corejs: 3, | |
// or completely control the exclude rule (note that you | |
// can't use both "include_node_modules" and "exclude" at | |
// the same time) | |
// exclude: /bower_components/ | |
}, | |
); | |
/* | |
* ENTRY CONFIG | |
* | |
* Add 1 entry for each "page" of your app | |
* (including one that's included on every page - e.g. "app") | |
* | |
* Each entry will result in one JavaScript file (e.g. app.js) | |
* and one CSS file (e.g. app.css) if you JavaScript imports CSS. | |
*/ | |
Encore.splitEntryChunks() | |
.addEntry('app', './resources/assets/js/entries/app.ts') | |
// .addEntry('errors', './resources/assets/js/entries/errors.ts') | |
.addEntry('home', './resources/assets/js/entries/home.ts') | |
.addEntry('profile', './resources/assets/js/entries/profile.ts') | |
.addEntry('checkout', './resources/assets/js/entries/checkout.ts') | |
.addEntry('product-list', './resources/assets/js/entries/product-list.ts') | |
.addEntry('product-view', './resources/assets/js/entries/product-view.ts') | |
.enableVersioning(Encore.isProduction()) | |
.enableIntegrityHashes(Encore.isProduction()) | |
.enableSingleRuntimeChunk() | |
.configureSplitChunks(() => ({ | |
chunks: 'all', | |
})) | |
.autoProvidejQuery() // uncomment if you're having problems with a jQuery plugin | |
.configureFriendlyErrorsPlugin() | |
// uncomment if you use TypeScript | |
.enableTypeScriptLoader(); | |
// .enableHandlebarsLoader() | |
// .enableForkedTypeScriptTypesChecking() | |
// .configureFilenames({ | |
// images: '[path][name].[ext]', | |
// }) | |
// Retrieve the config | |
const config = Encore.getWebpackConfig(); | |
if (Encore.isProduction()) { | |
config.devtool = 'source-map'; | |
} else { | |
Encore.addLoader({ | |
test: [/\.ts$/, /\.scss/], | |
use: ['cache-loader', 'babel-loader'], | |
include: [path.resolve('resources/assets/**/*'), path.resolve('node_modules')], | |
}); | |
// Change the kind of source map generated in development mode | |
config.devtool = 'inline-source-map'; | |
// USE cheap for Debugging in Chrome | |
// config.devtool = 'cheap-module-eval-source-map'; | |
// | |
config.optimization.minimize = false; | |
Encore.configureWatchOptions(function(watchOptions) { | |
watchOptions.poll = 1000; | |
watchOptions.aggregateTimeout = 1000; | |
watchOptions.ignored = /node_modules/; | |
}); | |
//Use below options when you need to debug webpack build | |
config.stats = { | |
// assets: true, | |
// builtAt: true, | |
cachedAssets: true, | |
errors: true, | |
errorDetails: true, | |
// reasons: true, | |
timings: true, | |
// warnings: true, | |
}; | |
config.devServer = { | |
host: 'web-app.local', | |
port: 9000, | |
historyApiFallback: true, | |
disableHostCheck: true, | |
public: 'web-app.local', | |
allowedHosts: ['app.local'], | |
contentBase: path.join(__dirname, 'public'), | |
proxy: { | |
'*': { | |
target: 'http://app.local:9000', | |
pathRewrite: { | |
'/[0-9]+': '', | |
}, | |
}, | |
}, | |
}; | |
} | |
// Export the config (be careful not to call | |
// getWebpackConfig() again) | |
module.exports = config; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment