Base code for preact and devt server

This commit is contained in:
Luc
2020-03-17 16:50:27 +01:00
parent b78b60e0a3
commit 5b036cde29
33 changed files with 12062 additions and 278 deletions

6
.babelrc Normal file
View File

@@ -0,0 +1,6 @@
{
"presets": [
"@babel/preset-env",
["@babel/preset-react", { "pragma": "h", "pragmaFrag": "Fragment" }]
]
}

13
.prettierrc Normal file
View File

@@ -0,0 +1,13 @@
{
"trailingComma": "es5",
"tabWidth": 4,
"semi": false,
"overrides": [
{
"files": "*.js",
"options": {
"parser": "babel"
}
}
]
}

17
.travis.yml Normal file
View File

@@ -0,0 +1,17 @@
language: node_js
node_js:
- "lts/*"
cache:
directories:
- "node_modules"
sudo: false
install:
- npm install
script:
- echo "build index.html"
- npm run build
notifications:
email:
on_success: change
on_failure: change

View File

@@ -1,8 +1,44 @@
# ESP3D-WEBUI
# ESP3D-WEBUI 3.0
using Preact per @aganov suggestion
## Not started yet - be patient...
## Not started in alpha stage - be patient...
[![Build Status](https://travis-ci.org/luc-github/ESP3D-WEBUI.svg?branch=3.0)](https://travis-ci.org/luc-github/ESP3D-WEBUI)
[Latest development version ![Development Version](https://img.shields.io/badge/Devt-v3.0-yellow?style=plastic) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/luc-github/ESP3D-WEBUI/3.0?style=plastic)](https://github.com/luc-github/ESP3D-WEBUI/tree/3.0) ![Travis (.org) branch](https://img.shields.io/travis/luc-github/ESP3D-WEBUI/3.0?style=plastic)
### Setup development tools
1 - Install current nodejs LTS (currently using v10.15.3)
2 - Download all necessary packages
```
npm install
```
### Start dev server
http://localhost:8080
```
npm run start
```
### Build index.html.gz to /dist folder
```
npm run build
```
### Code beautify with prettier
use pluggin or cli
```
npm install --global prettier
```
the config file is .prettierrc
a batch is available if you need : prettyfiles.bat, it is just automating the following commands:
prettier --config .prettierrc --write "{src/**/,webpack/**/}*.js"
prettier --config .prettierrc --write src/**/*.html"
[Latest development version ![Development Version](https://img.shields.io/badge/Devt-v3.0-yellow?style=plastic) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/luc-github/ESP3D-WEBUI/3.0?style=plastic)](https://github.com/luc-github/ESP3D-WEBUI/tree/3.0) ![Travis (.org) branch](https://img.shields.io/travis/luc-github/ESP3D-WEBUI/3.0?style=plastic)

View File

@@ -1,275 +0,0 @@
var gulp = require('gulp'),
jshint = require('gulp-jshint'),
gulpif = require('gulp-if'),
concat = require('gulp-concat'),
uglify = require('gulp-uglify'),
cleanCSS = require('gulp-clean-css'),
removeCode = require('gulp-remove-code'),
merge = require('merge-stream'),
del = require('del'),
zip = require('gulp-zip'),
gzip = require('gulp-gzip'),
htmlmin = require('gulp-htmlmin'),
replace = require('gulp-replace'),
fs = require('fs'),
smoosher = require('gulp-smoosher');
size = require('gulp-filesize');
var en_lang = true;
var fr_lang = false;
var es_lang = false;
var de_lang = false;
var it_lang = false;
var pl_lang = false;
var ptbr_lang = false;
var ru_lang = false;
var uk_lang = false;
function clean() {
return del(['dist']);
}
function clean2() {
return del(['dist/js', 'dist/css']);
}
function lint() {
return gulp.src('www/js/**/app.js')
.pipe(jshint())
.pipe(jshint.reporter('default'));
}
function Copytest() {
return merge(
gulp.src(['www/index.html'])
.pipe(removeCode({production: false}))
.pipe(removeCode({cleanheader: true}))
.pipe(gulp.dest('dist')),
gulp.src(['www/images/**/*.*'])
.pipe(gulp.dest('dist/images'))
)
}
function Copy() {
return merge(
gulp.src(['www/index.html'])
.pipe(removeCode({production: true}))
.pipe(removeCode({cleanheader: true}))
.pipe(gulp.dest('dist')),
gulp.src(['www/images/**/*.*'])
.pipe(gulp.dest('dist/images'))
)
}
function concatApptest() {
return merge(
gulp.src([ 'www/js/**/*.js'])
.pipe(concat('app.js'))
.pipe(removeCode({production: false}))
.pipe(removeCode({cleanheader: true}))
.pipe(gulp.dest('./dist/js')),
gulp.src([ 'www/css/**/*.css'])
.pipe(concat('style.css'))
.pipe(gulp.dest('./dist/css/'))
)
}
function concatApp() {
return merge(
gulp.src([ 'www/js/**/*.js'])
.pipe(concat('app.js'))
.pipe(removeCode({production: true}))
.pipe(removeCode({cleanheader: true}))
.pipe(gulp.dest('./dist/js')),
gulp.src([ 'www/css/**/*.css'])
.pipe(concat('style.css'))
.pipe(gulp.dest('./dist/css/'))
)
}
function replaceSVG() {
return gulp.src('dist/index.html')
.pipe(replace(/<!-- replaceSVG -->(.*?)<!-- \/replaceSVG -->/g, function (match, p1) {
return fs.readFileSync('dist/images/jogdial.svg', 'utf8');
}))
.pipe(gulp.dest('dist'))
}
function clearlang() {
// fetch command line arguments
console.log("Enable Language:");
const arg = (argList => {
let arg = {}, a, opt, thisOpt, curOpt;
for (a = 0; a < argList.length; a++) {
thisOpt = argList[a].trim();
opt = thisOpt.replace(/^\-+/, '');
if (opt === thisOpt) {
// argument value
if (curOpt) arg[curOpt] = opt;
curOpt = null;
}
else {
// argument name
curOpt = opt;
arg[curOpt] = true;
}
}
return arg;
})(process.argv);
if ((typeof arg.lang == 'undefined') || (arg.lang == 'all')) {
en_lang = true;
fr_lang = true;
es_lang = true;
de_lang = true;
it_lang = true;
pl_lang = true;
ptbr_lang = true;
ru_lang = true;
uk_lang = true;
}
if (arg.lang == 'en'){
en_lang = true;
}
if(en_lang){
console.log("en");
}
if (arg.lang == 'fr'){
fr_lang = true;
}
if(fr_lang){
console.log("fr");
}
if (arg.lang == 'es'){
es_lang = true;
}
if(es_lang){
console.log("es");
}
if (arg.lang == 'de'){
de_lang = true;
}
if(de_lang){
console.log("de");
}
if (arg.lang == 'it'){
it_lang = true;
}
if(it_lang){
console.log("it");
}
if (arg.lang == 'pl'){
pl_lang = true;
}
if(pl_lang){
console.log("pl");
}
if (arg.lang == 'ptbr'){
ptbr_lang = true;
}
if(ptbr_lang){
console.log("ptbr");
}
if (arg.lang == 'ru'){
ru_lang = true;
}
if(ru_lang){
console.log("ru");
}
if (arg.lang == 'uk'){
uk_lang = true;
}
if(uk_lang){
console.log("uk");
}
return gulp.src('dist/js/app.js')
.pipe(removeCode({de_lang_disabled: !de_lang}))
.pipe(removeCode({en_lang_disabled: !en_lang}))
.pipe(removeCode({es_lang_disabled: !es_lang}))
.pipe(removeCode({fr_lang_disabled: !fr_lang}))
.pipe(removeCode({it_lang_disabled: !it_lang}))
.pipe(removeCode({pl_lang_disabled: !pl_lang}))
.pipe(removeCode({ptbr_lang_disabled: !ptbr_lang}))
.pipe(removeCode({ru_lang_disabled: !ru_lang}))
.pipe(removeCode({uk_lang_disabled: !uk_lang}))
.pipe(gulp.dest('./dist/js/'))
}
function minifyApp() {
return merge(
gulp.src(['dist/js/app.js'])
.pipe(uglify({mangle: true}))
.pipe(gulp.dest('./dist/js/')),
gulp.src('dist/css/style.css')
.pipe(cleanCSS({debug: true}, function(details) {
console.log(details.name + ': ' + details.stats.originalSize);
console.log(details.name + ': ' + details.stats.minifiedSize);
}))
.pipe(gulp.dest('./dist/css/')),
gulp.src('dist/index.html')
.pipe(htmlmin({collapseWhitespace: true, minifyCSS: true}))
.pipe(gulp.dest('dist'))
)
}
function includehtml() {
return merge(
gulp.src('dist/index.html')
.pipe(replace(/<file-include w3-include-html="'sub\/(.*?)'"><\/file-include>/g, function (match, p1) {
return fs.readFileSync('www/sub/' + p1, 'utf8');
}))
.pipe(gulp.dest('dist/'))
)
}
function smoosh() {
return gulp.src('dist/index.html')
.pipe(smoosher())
.pipe(gulp.dest('dist'))
}
function compress() {
return gulp.src('dist/index.html')
.pipe(gzip({ gzipOptions: { level: 9} }))
.pipe(gulp.dest('.'))
.pipe(size());
}
gulp.task(clean);
gulp.task(lint);
gulp.task(Copy);
gulp.task(Copytest);
gulp.task(replaceSVG);
gulp.task(concatApp);
gulp.task(concatApptest);
gulp.task(minifyApp);
gulp.task(smoosh);
gulp.task(clean2);
gulp.task(clearlang)
var defaultSeries = gulp.series(clean, lint, Copy, concatApp, minifyApp, includehtml, includehtml, smoosh);
//var packageSeries = gulp.series(clean, lint, Copy, concatApp, minifyApp, smoosh, compress);
var packageSeries = gulp.series(clean, lint, Copy, concatApp, includehtml, includehtml, replaceSVG, clearlang, minifyApp, smoosh, compress, clean2);
var package2Series = gulp.series(clean, lint, Copy, concatApp, includehtml, includehtml, replaceSVG, smoosh);
var package2testSeries = gulp.series(clean, lint, Copytest, concatApptest, includehtml, includehtml, replaceSVG, smoosh);
gulp.task('default', defaultSeries);
gulp.task('package', packageSeries);
gulp.task('package2', package2Series);
gulp.task('package2test', package2testSeries);

1
images/logo.svg Normal file
View File

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 158 KiB

1
images/logob&W.svg Normal file
View File

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB

11437
package-lock.json generated Normal file
View File

File diff suppressed because it is too large Load Diff

53
package.json Normal file
View File

@@ -0,0 +1,53 @@
{
"name": "ESP3D-WebUI",
"version": "3.0.0",
"description": "Preact version of WebUI for ESP3D per @aganov suggestion",
"main": "index.js",
"scripts": {
"build": "cross-env NODE_ENV=production webpack --mode=production",
"clean": "rm -rf dist",
"start": "cross-env NODE_ENV=development webpack-dev-server --open --mode=development"
},
"keywords": [],
"type": "git",
"repository": "https://github.com/luc-github/ESP3D-WEBUI",
"author": "",
"license": "(ISC OR GPL-3.0)",
"devDependencies": {
"@babel/core": "latest",
"@babel/preset-env": "latest",
"@babel/preset-react": "latest",
"@babel/register": "latest",
"babel-loader": "latest",
"compression-webpack-plugin": "latest",
"cross-env": "latest",
"css-loader": "latest",
"html-minifier-webpack-plugin": "latest",
"html-webpack-inline-source-plugin": "latest",
"html-webpack-plugin": "latest",
"mini-css-extract-plugin": "latest",
"node-sass": "latest",
"optimize-css-assets-webpack-plugin": "latest",
"postcss-flexbugs-fixes": "latest",
"postcss-import": "latest",
"postcss-loader": "latest",
"postcss-preset-env": "latest",
"postcss-safe-parser": "latest",
"remove-files-webpack-plugin": "latest",
"sass-loader": "latest",
"style-loader": "latest",
"terser-webpack-plugin": "latest",
"webpack": "latest",
"webpack-cli": "latest",
"webpack-dev-server": "latest",
"webpack-merge": "latest",
"webpack-modules": "latest"
},
"dependencies": {
"bootstrap": "latest",
"history": "latest",
"preact": "latest",
"preact-feather": "latest",
"preact-router": "latest"
}
}

12
postcss.config.js Normal file
View File

@@ -0,0 +1,12 @@
module.exports = {
plugins: [
require('postcss-import'),
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009'
},
stage: 3
})
]
}

4
prettyfiles.bat Normal file
View File

@@ -0,0 +1,4 @@
cd %~dp0
cmd.exe /c prettier --config .prettierrc --write "{src/**/,webpack/**/}*.js"
cmd.exe /c prettier --config .prettierrc --write "src/**/*.html"
pause

15
src/components/app.js Normal file
View File

@@ -0,0 +1,15 @@
import { h, createContext } from "preact"
import "../stylesheets/application.scss"
import { useEffect } from "preact/hooks"
import { Esp3dVersion } from "./version"
export function App() {
useEffect(() => {
console.log("Page loaded")
}, [])
return (
<center>
ESP3D v<Esp3dVersion />
</center>
)
}

View File

@@ -0,0 +1,3 @@
import { h } from "preact"
export const Esp3dVersion = () => <span>0.0.0.1</span>

12
src/index.html Normal file
View File

@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>ESP3D</title>
</head>
<body></body>
</html>

4
src/index.js Normal file
View File

@@ -0,0 +1,4 @@
import { h, render } from "preact"
import { App } from "./components/app"
render(<App />, document.body)

View File

@@ -0,0 +1,34 @@
@import "~bootstrap/scss/root";
@import "~bootstrap/scss/reboot";
@import "~bootstrap/scss/type";
// @import "~bootstrap/scss/images";
// @import "~bootstrap/scss/code";
@import "~bootstrap/scss/grid";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/buttons";
@import "~bootstrap/scss/transitions";
@import "~bootstrap/scss/dropdown";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/input-group";
@import "~bootstrap/scss/custom-forms";
@import "~bootstrap/scss/nav";
@import "~bootstrap/scss/navbar";
@import "~bootstrap/scss/card";
// @import "~bootstrap/scss/breadcrumb";
// @import "~bootstrap/scss/pagination";
@import "~bootstrap/scss/badge";
// @import "~bootstrap/scss/jumbotron";
@import "~bootstrap/scss/alert";
// @import "~bootstrap/scss/progress";
@import "~bootstrap/scss/media";
@import "~bootstrap/scss/list-group";
// @import "~bootstrap/scss/close";
// @import "~bootstrap/scss/toasts";
@import "~bootstrap/scss/modal";
@import "~bootstrap/scss/tooltip";
// @import "~bootstrap/scss/popover";
// @import "~bootstrap/scss/carousel";
// @import "~bootstrap/scss/spinners";
@import "~bootstrap/scss/utilities";
// @import "~bootstrap/scss/print";

View File

@@ -0,0 +1,14 @@
$font-size-root: 18px !default;
@function pxtorem($px) {
$base: null !default;
@if unit($font-size-root) == "px" {
$base: $font-size-root;
} @else if unit($font-size-root) == "%" {
$base: ($font-size-root / 100%) * 16px;
} @else if unit($font-size-root) == "" {
$base: $font-size-root * 16px;
}
@return (floor(ceil(($px / $base) * 1000)) / 1000) * 1rem;
}

View File

@@ -0,0 +1,64 @@
@import "~bootstrap/scss/functions";
@import "~bootstrap/scss/variables";
@import "~bootstrap/scss/mixins";
$body-bg: #f7f7f7;
$color-white: #ffffff;
$color-muted: #928886;
// Primary
$color-primary-50: #fdeee7;
$color-primary-100: #fbd5c2;
$color-primary-200: #f8b999;
$color-primary-300: #f59c70;
$color-primary-400: #f38752;
$color-primary-500: #f17233;
$color-primary-600: #ef6a2e;
$color-primary-700: #ed5f27;
$color-primary-800: #eb5520;
$color-primary-900: #e74214;
$color-primary-a100: #ffffff;
$color-primary-a200: #ffe8e3;
$color-primary-a300: #ffbeb0;
$color-primary-a400: #ffaa96;
// Gray
$gray-base: $gray-900;
$gray-darkest: $gray-800;
$gray-darker: $gray-700;
$gray-dark: $gray-600;
$gray: $gray-500;
$gray-light: $gray-400;
$gray-lighter: $gray-300;
$gray-lightest: $gray-200;
// Brand
$brand-default: $gray-lighter;
$brand-default-hover: $gray-lightest;
$brand-default-active: $gray-light;
$brand-default-100: $gray-100;
$brand-primary: $color-primary-500;
$brand-primary-hover: $color-primary-400;
$brand-primary-active: $color-primary-600;
$brand-primary-400: $color-primary-400;
$brand-primary-100: $color-primary-100;
$brand-dark: $gray-darker;
$brand-dark-hover: $gray-dark;
$brand-dark-active: $gray-darkest;
$brand-dark-100: $gray-100;
// Text
$title-color: $gray-darkest;
$subtitle-color: $gray-darker;
$text-color: $gray-dark;
$text-muted: $color-muted;
// Headings
$h1-font-size: pxtorem(36px);
$h2-font-size: pxtorem(30px);
$h3-font-size: pxtorem(24px);
$h4-font-size: pxtorem(18px);
$h5-font-size: pxtorem(14px);
$h6-font-size: pxtorem(12px);

View File

@@ -0,0 +1,9 @@
@import "functions";
@import "vars";
@import "bootstrap";
@import "components/navbar";
body {
overflow-x: hidden;
font-size: 1rem;
}

View File

@@ -0,0 +1,68 @@
.header {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 56px;
padding: 0;
background: #673AB7;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
z-index: 50;
h1 {
float: left;
margin: 0;
padding: 0 15px;
font-size: 24px;
line-height: 56px;
font-weight: 400;
color: #FFF;
}
version {
float: right;
margin: 0;
padding: 0 15px;
font-size: 14px;
line-height: 56px;
font-weight: 400;
color: #FFF;
a {
display: inline-block;
height: 56px;
line-height: 56px;
padding: 0 15px;
min-width: 50px;
text-align: center;
background: rgba(255,255,255,0);
text-decoration: none;
color: #EEE;
will-change: background-color;
&:hover, &:active {
background: rgba(255,255,255,0.3);
}
}
}
nav {
font-size: 100%;
a {
display: inline-block;
height: 56px;
line-height: 56px;
padding: 0 15px;
min-width: 50px;
text-align: center;
background: rgba(255,255,255,0);
text-decoration: none;
color: #EEE;
will-change: background-color;
&:hover, &:active {
background: rgba(255,255,255,0.3);
}
}
}
}

7
webpack.config.js Normal file
View File

@@ -0,0 +1,7 @@
// Imports: Dependencies
const path = require("path")
require("@babel/register")
module.exports = (env, argv) => {
return require(`./webpack/${argv.mode}.js`)
}

41
webpack/development.js Normal file
View File

@@ -0,0 +1,41 @@
import merge from "webpack-merge"
import environment from "./environment"
module.exports = merge(environment, {
devtool: "inline-source-map",
devServer: {
before: function(app, server, compiler) {
app.get("/command", function(req, res) {
var url = req.originalUrl
if (url.indexOf("ESP800") != -1) {
res.json({
FWVersion: "3.0.0.a27",
FWTarget: "???",
SDConnection: "None",
Authentication: "Disabled",
WebCommunication: "Synchronous",
WebSocketIP: "192.168.1.43",
WebSocketport: "81",
Hostname: "esp3d",
WiFiMode: "STA",
WebUpdate: "Enabled",
Filesystem: "SPIFFS",
Time: "None",
})
} else {
res.json({ custom: "response2" })
}
})
app.get("/camera", function(req, res) {
//res.send("You should not be there");
res.redirect("/")
})
app.get("/login", function(req, res) {
res.redirect("/")
})
app.get("/settings", function(req, res) {
res.redirect("/")
})
},
},
})

35
webpack/environment.js Normal file
View File

@@ -0,0 +1,35 @@
import { environmentPlugins } from "./plugins"
import MiniCssExtractPlugin from "mini-css-extract-plugin"
const devMode = process.env.NODE_ENV !== "production"
module.exports = {
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: devMode
? "style-loader"
: MiniCssExtractPlugin.loader,
options: {},
},
{ loader: "css-loader", options: { sourceMap: devMode } },
{
loader: "postcss-loader",
options: { sourceMap: devMode },
},
{ loader: "sass-loader", options: { sourceMap: devMode } },
],
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
],
},
plugins: environmentPlugins,
}

View File

@@ -0,0 +1,15 @@
/**
* Prepare compressed versions of assets to serve them with Content-Encoding
* Docs: https://github.com/webpack-contrib/compression-webpack-plugin
*/
const CompressionPlugin = require("compression-webpack-plugin")
const config = {
filename: "[path].gz[query]",
algorithm: "gzip",
cache: true,
test: /\.(html)$/,
}
export default () => new CompressionPlugin(config)

View File

@@ -0,0 +1,14 @@
/**
* A Webpack plugin to minify HTML files.
* Docs: https://github.com/Maxwellewxam/html-minifier-webpack-plugin
*/
import HtmlMinifierWebpackPlugin from "html-minifier-webpack-plugin"
const devMode = process.env.NODE_ENV !== "production"
const config = {
collapseWhitespace: devMode ? true : false,
}
export default () => new HtmlMinifierWebpackPlugin(config)

View File

@@ -0,0 +1,8 @@
/**
* Embed javascript and css source inline when using the webpack dev server or middleware
* Docs: https://github.com/DustinJackson/html-webpack-inline-source-plugin
*/
const HtmlWebpackInlineSourcePlugin = require("html-webpack-inline-source-plugin")
export default () => new HtmlWebpackInlineSourcePlugin()

View File

@@ -0,0 +1,19 @@
/**
* Plugin that simplifies creation of HTML files to serve your bundles
* Docs: https://github.com/jantimon/html-webpack-plugin
*/
import HtmlWebpackPlugin from "html-webpack-plugin"
const devMode = process.env.NODE_ENV !== "production"
const config = {
inlineSource: ".(js|css)$",
template: "./src/index.html",
filename: "./index.html",
minify: true,
inject: true,
hash: devMode ? true : false,
}
export default () => new HtmlWebpackPlugin(config)

21
webpack/plugins/index.js Normal file
View File

@@ -0,0 +1,21 @@
import compressionPlugin from "./compression-plugin"
import htmlWebpackInlineSourcePlugin from "./html-webpack-inline-source-plugin"
import optimizeCSSAssetsPlugin from "./optimize-css-assets-webpack-plugin"
import htmlWebpackPlugin from "./html-webpack-plugin"
import htmlMinifierWebpackPlugin from "./html-minifier-webpack-plugin"
import miniCssExtractPlugin from "./mini-css-extract-plugin"
import removeFilesWebpackPlugin from "./remove-files-webpack-plugin"
import terserPlugin from "./terser-plugin"
export const environmentPlugins = [htmlWebpackPlugin(), miniCssExtractPlugin()]
export const optimizationPlugins = {
minimizer: [terserPlugin(), optimizeCSSAssetsPlugin()],
}
export const productionPlugins = [
htmlWebpackInlineSourcePlugin(),
htmlMinifierWebpackPlugin(),
compressionPlugin(),
removeFilesWebpackPlugin(),
]

View File

@@ -0,0 +1,12 @@
/**
* This plugin extracts CSS into separate files.
* It creates a CSS file per JS file which contains CSS.
* It supports On-Demand-Loading of CSS and SourceMaps.
*
* Docs: https://github.com/webpack-contrib/mini-css-extract-plugin
*/
import MiniCssExtractPlugin from "mini-css-extract-plugin"
const devMode = process.env.NODE_ENV !== "production"
export default () => new MiniCssExtractPlugin({})

View File

@@ -0,0 +1,16 @@
/**
* A Webpack plugin to optimize \ minimize CSS assets.
* Docs: https://github.com/NMFR/optimize-css-assets-webpack-plugin
*/
import OptimizeCSSAssetsPlugin from "optimize-css-assets-webpack-plugin"
const safePostCssParser = require("postcss-safe-parser")
export default () =>
new OptimizeCSSAssetsPlugin({
parser: safePostCssParser,
map: {
inline: false,
annotation: true,
},
})

View File

@@ -0,0 +1,26 @@
/**
* A plugin for webpack which removes files and folders before and after compilation.
* Docs: https://github.com/Amaimersion/remove-files-webpack-plugin
*/
const RemoveFilesWebpackPlugin = require("remove-files-webpack-plugin")
const config = {
before: {
include: ["dist"],
},
after: {
exclude: ["dist/index.html.gz"],
test: [
{
folder: "./dist",
method: filePath => {
return new RegExp(/\.*$/, "m").test(filePath)
},
},
],
log: true,
},
}
export default () => new RemoveFilesWebpackPlugin(config)

View File

@@ -0,0 +1,34 @@
/**
* This plugin is used to minify your JavaScript.
* Docs: https://github.com/webpack-contrib/terser-webpack-plugin
*/
import TerserPlugin from "terser-webpack-plugin"
const config = {
parallel: true,
cache: false,
sourceMap: false,
terserOptions: {
parse: {
// Let terser parse ecma 8 code but always output
// ES5 compliant code for older browsers
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
comparisons: false,
},
mangle: {
safari10: true,
},
output: {
ecma: 5,
comments: false,
ascii_only: true,
},
},
}
export default () => new TerserPlugin(config)

8
webpack/production.js Normal file
View File

@@ -0,0 +1,8 @@
import merge from "webpack-merge"
import environment from "./environment"
import { productionPlugins, optimizationPlugins } from "./plugins"
module.exports = merge(environment, {
optimization: optimizationPlugins,
plugins: productionPlugins,
})