Last active
May 29, 2021 08:07
-
-
Save martinherweg/64ac8f3123044cb2777d6a9fcd9f6fdf to your computer and use it in GitHub Desktop.
Webpack + BrowserSync + HMR
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
/** | |
|-------------------------------------------------------------------------- | |
| gulp browser-sync | |
|-------------------------------------------------------------------------- | |
* | |
* Browser Sync | |
* @description Refresh the Brwoser after File Change. | |
* Combined with webpack for HMR or Content Reload | |
* | |
* @package generator-mh-boilerplate | |
* @author Martin Herweg <[email protected]> | |
*/ | |
/* | |
|-------------------------------------------------------------------------- | |
| browser-sync.js | |
|-------------------------------------------------------------------------- | |
*/ | |
import config from '../../config.json'; | |
import gulp from 'gulp'; | |
import browserSync from 'browser-sync'; | |
import webpack from 'webpack'; | |
import webpackDevMiddleware from 'webpack-dev-middleware'; | |
import webpackHotMiddleware from 'webpack-hot-middleware'; | |
import webpackSettings from '../../webpack/webpack.config.babel'; | |
import yargs from 'yargs'; | |
const argv = yargs.argv; | |
const env = argv.env || 'development'; | |
const browserSyncTask = () => { | |
if(env !== 'browser-sync') return; | |
//console.log(JSON.stringify(webpackSettings, ' ', 4)); | |
const bundler = webpack(webpackSettings); | |
browserSync.init({ | |
proxy: { | |
target: config.proxy, | |
ws: true, | |
}, | |
ghostMode: { | |
clicks: true, | |
forms: true, | |
scroll: false, | |
}, | |
logLevel: 'debug', | |
open: false, | |
stream: true, | |
ui: { | |
port: 8090, | |
}, | |
middleware: [ | |
webpackDevMiddleware(bundler, { | |
quiet: true, | |
path: webpackSettings.output.path, | |
publicPath: webpackSettings.output.publicPath, | |
stats: { | |
colors: true, | |
}, | |
}), | |
webpackHotMiddleware(bundler, { | |
log: () => {}, | |
}), | |
], | |
watchOptions: { | |
ignoreInitial: true | |
}, | |
files: [ | |
`${config.dist.views}**/*.{php,html,twig}`, | |
`${config.dist.images.base}**/*.{jpg,png,gif,svg}`, | |
`${config.dist}**/*.{css}`, | |
], | |
}); | |
browserSync.watch(config.dist.base + '**/*.css', function(event, file) { | |
console.log(event, ' event on ', file); | |
if (event === 'change') { | |
browserSync.reload('*.css'); | |
} | |
}); | |
}; | |
const browserSyncReload = () => { | |
browserSync.reload(); | |
}; | |
gulp.task('browser-sync', browserSyncTask); | |
gulp.task('bs-reload', browserSyncReload); | |
export { browserSyncTask, browserSyncReload }; |
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
import webpack from 'webpack'; | |
import { getIfUtils, removeEmpty } from 'webpack-config-utils'; | |
import path from 'path'; | |
import config from '../config.json'; | |
import ExtractTextPlugin from 'extract-text-webpack-plugin'; | |
import HtmlWebpackPlugin from 'html-webpack-plugin'; | |
import WriteFilePlugin from 'write-file-webpack-plugin'; | |
import StylelintPlugin from 'stylelint-webpack-plugin'; | |
const { ifProduction, ifNotProduction } = getIfUtils(process.env.NODE_ENV); | |
/* | |
|-------------------------------------------------------------------------- | |
| Setting some paths for our Application | |
|-------------------------------------------------------------------------- | |
*/ | |
const BASE_PATH = path.join(path.resolve(__dirname, '../')); | |
const ASSETS_ROOT = path.resolve(BASE_PATH, config.dist.base); | |
/* | |
|-------------------------------------------------------------------------- | |
| Hot Middleware Client | |
|-------------------------------------------------------------------------- | |
*/ | |
const hot_client = 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true&overlay=true'; | |
/* | |
|-------------------------------------------------------------------------- | |
| Defining Entry Points, could be used to manually split Parts of the Application, for example | |
| Admin Javascript and FrontEnd JavaScript | |
|-------------------------------------------------------------------------- | |
*/ | |
const entry_points = { | |
app: './src/js/app.js', | |
}; | |
ifNotProduction(Object.keys(entry_points).forEach(entry => entry_points[entry] = [hot_client].concat(entry_points[entry]))); | |
function assetsPath(_path) { | |
return path.posix.join('/assets/', _path); | |
} | |
let chunks = []; | |
const chunks_inject = [ | |
{ | |
filename: path.resolve(`${config.dist.views}parts/site-header.html`), | |
file: config.src.views + 'parts/site-header.html', | |
inject: false | |
}, | |
{ | |
filename: path.resolve(`${config.dist.views}parts/site-scripts.html`), | |
file: config.src.views + 'parts/site-scripts.html', | |
inject: false | |
}, | |
]; | |
chunks_inject.forEach((chunk) => { | |
const plugin = new HtmlWebpackPlugin({ | |
filename: chunk.filename, | |
template: chunk.file, | |
inject: chunk.inject, | |
minify: false, | |
// necessary to consistently work with multiple chunks via CommonsChunkPlugin | |
chunksSortMode: 'dependency', | |
}); | |
chunks.push(plugin); | |
}); | |
const extractSass = new ExtractTextPlugin({ | |
filename: assetsPath('css/[name].css'), | |
}); | |
/* | |
|-------------------------------------------------------------------------- | |
| return webpack config object | |
|-------------------------------------------------------------------------- | |
*/ | |
export default { | |
devtool: ifProduction('source-map', 'cheap-module-eval-source-map'), | |
context: BASE_PATH, | |
// entry is a function so that we can use environment variables | |
entry: removeEmpty(entry_points), | |
output: { | |
path: ASSETS_ROOT, | |
publicPath: '', | |
filename: assetsPath('js/[name].js'), | |
}, | |
resolve: { | |
extensions: ['.js', '.vue', '.json'], | |
modules: [ | |
resolve('src'), | |
resolve('node_modules'), | |
], | |
alias: { | |
'vue$': 'vue/dist/vue.common.js', | |
'src': resolve('src'), | |
}, | |
}, | |
module: { | |
rules: [ | |
{ | |
test: /\.(js|vue)$/, | |
loader: 'eslint-loader', | |
enforce: 'pre', | |
include: resolve('src'), | |
options: { | |
formatter: require('eslint-formatter-pretty'), | |
}, | |
}, | |
{ | |
test: /\.vue$/, | |
loader: 'vue-loader', | |
}, | |
{ | |
test: /\.js$/, | |
loader: 'babel-loader', | |
include: resolve('src'), | |
}, | |
{ | |
test: /\.json$/, | |
loader: 'json-loader', | |
}, | |
{ | |
test: /\.scss$/, | |
include: resolve('src/scss'), | |
exclude: [resolve('node_modules'), resolve('dist/')], | |
loader: extractSass.extract({ | |
loader: [ | |
{ | |
loader: 'css-loader', | |
options: { | |
sourceMap: true, | |
}, | |
}, | |
{ | |
loader: 'sass-loader', | |
options: { | |
sourceMap: true, | |
}, | |
}, | |
], | |
}), | |
}, | |
], | |
}, | |
plugins: removeEmpty([ | |
ifProduction(new webpack.DefinePlugin({ | |
'process.env': { | |
NODE_ENV: '"production"', | |
}, | |
})), | |
new webpack.HotModuleReplacementPlugin(), | |
new StylelintPlugin({ | |
context: resolve('src/scss/'), | |
syntax: 'scss', | |
}), | |
extractSass, | |
...chunks, | |
new WriteFilePlugin({ | |
test: /^(?!.+(?:hot-update.(js|json))).+$/, | |
}), | |
]), | |
}; | |
function resolve(dir) { | |
return path.join(__dirname, '..', dir); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment