Compare commits
10 commits
bb40c09cda
...
602dbf5f3f
Author | SHA1 | Date | |
---|---|---|---|
602dbf5f3f | |||
4679d04076 | |||
1879d3a420 | |||
e52dbb6b9a | |||
d057048c66 | |||
4a572324e0 | |||
bf43bdba09 | |||
5b504ae3d6 | |||
75f80460f5 | |||
7fa7dd4e0f |
14 changed files with 5376 additions and 6226 deletions
11255
package-lock.json
generated
11255
package-lock.json
generated
File diff suppressed because it is too large
Load diff
51
package.json
51
package.json
|
@ -11,31 +11,30 @@
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@beyonk/google-fonts-webpack-plugin": "^1.2.3",
|
"chart.js": "^4.4.2",
|
||||||
"chart.js": "^2.9.3",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"clean-webpack-plugin": "^3.0.0",
|
"copy-webpack-plugin": "^12.0.2",
|
||||||
"copy-webpack-plugin": "^5.1.1",
|
"css-loader": "^7.1.1",
|
||||||
"css-loader": "^3.4.2",
|
"file-loader": "^6.2.0",
|
||||||
"file-loader": "^5.1.0",
|
"html-webpack-plugin": "^5.6.0",
|
||||||
"google-fonts-webpack-plugin": "^0.4.4",
|
"idb-keyval": "^6.2.1",
|
||||||
"html-loader": "^0.5.5",
|
"reset-css": "^5.0.2",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"string-replace-loader": "^3.1.0",
|
||||||
"idb-keyval": "^3.2.0",
|
"style-loader": "^4.0.0",
|
||||||
"reset-css": "^5.0.1",
|
"svelte": "^4.2.13",
|
||||||
"serviceworker-webpack-plugin": "^1.0.1",
|
"svelte-loader": "^3.2.0",
|
||||||
"string-replace-loader": "^2.2.0",
|
"terser-webpack-plugin": "^5.3.10",
|
||||||
"style-loader": "^1.1.3",
|
"uuid": "^9.0.1",
|
||||||
"svelte": "^3.4.1",
|
"webpack": "^5.91.0",
|
||||||
"svelte-loader": "^2.13.4",
|
"webpack-cli": "^5.1.4",
|
||||||
"uuid": "^3.4.0",
|
"webpack-dev-server": "^5.0.4",
|
||||||
"webpack": "^4.31.0",
|
"webpack-license-plugin": "^4.4.2",
|
||||||
"webpack-cli": "^3.3.2",
|
"webpack-merge": "^5.10.0",
|
||||||
"webpack-dev-server": "^3.4.1",
|
"workbox-broadcast-update": "^7.0.0",
|
||||||
"webpack-license-plugin": "^4.1.1",
|
"workbox-cacheable-response": "^7.0.0",
|
||||||
"webpack-merge": "^4.2.2",
|
"workbox-expiration": "^7.0.0",
|
||||||
"workbox-cacheable-response": "^5.0.0",
|
"workbox-routing": "^7.0.0",
|
||||||
"workbox-expiration": "^5.0.0",
|
"workbox-strategies": "^7.0.0",
|
||||||
"workbox-routing": "^5.0.0",
|
"workbox-window": "^7.0.0"
|
||||||
"workbox-strategies": "^5.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
shell.nix
Normal file
7
shell.nix
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
pkgs.mkShell {
|
||||||
|
# nativeBuildInputs is usually what you want -- tools you need to run
|
||||||
|
nativeBuildInputs = with pkgs.buildPackages; [
|
||||||
|
nodejs_18
|
||||||
|
];
|
||||||
|
}
|
|
@ -5,7 +5,16 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta name="description" content="Web app for keeping track of anything you want to count.">
|
<meta name="description" content="Web app for keeping track of anything you want to count.">
|
||||||
<title>NCounter</title>
|
<title>NCounter</title>
|
||||||
${require('./icon/html_code.html')}
|
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-touch-icon.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
|
||||||
|
<link rel="manifest" href="icons/site.webmanifest">
|
||||||
|
<link rel="mask-icon" href="icons/safari-pinned-tab.svg" color="#3a86b7">
|
||||||
|
<link rel="shortcut icon" href="icons/favicon.ico">
|
||||||
|
<meta name="msapplication-TileColor" content="#dce6ef">
|
||||||
|
<meta name="msapplication-config" content="icons/browserconfig.xml">
|
||||||
|
<meta name="theme-color" content="#dce6ef">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>
|
<noscript>
|
||||||
|
|
16
src/index.js
16
src/index.js
|
@ -1,10 +1,18 @@
|
||||||
import App from './ncounter/App.svelte';
|
import App from './ncounter/App.svelte';
|
||||||
import runtime from 'serviceworker-webpack-plugin/lib/runtime';
|
|
||||||
import 'reset-css/reset.css';
|
import 'reset-css/reset.css';
|
||||||
import './ncounter/site.css';
|
import './ncounter/site.css';
|
||||||
|
import {Workbox} from 'workbox-window/Workbox.mjs';
|
||||||
|
|
||||||
|
const app = new App({ target: document.body });
|
||||||
|
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
const registration = runtime.register();
|
const wb = new Workbox('sw.js');
|
||||||
}
|
|
||||||
|
|
||||||
new App({ target: document.body });
|
wb.addEventListener('message', async (event) => {
|
||||||
|
if (event.data.type === 'CACHE_UPDATED') {
|
||||||
|
app.SetUpdateAvailable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
wb.register();
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
<div class="about">
|
<div class="about">
|
||||||
<button class="close" on:click={ () => { dispatch('close'); } }><i class="material-icons">close</i></button>
|
<button class="close" on:click={ () => { dispatch('close'); } }><span class="material-symbols-outlined">close</span></button>
|
||||||
<header>
|
<header>
|
||||||
<h1>NCounter</h1>
|
<h1>NCounter</h1>
|
||||||
<h2>Release |BUILD_DATE|</h2>
|
<h2>Release |BUILD_DATE|</h2>
|
||||||
|
|
|
@ -4,8 +4,16 @@
|
||||||
<Counter counterId={ counter.id }></Counter>
|
<Counter counterId={ counter.id }></Counter>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
{#if showUpdateMessage}
|
||||||
|
<div class="update-message">
|
||||||
|
An update is available. <button class="reload" on:click="{ () => { window.location.reload(); } }">Load now</button><button class="later" on:click="{ () => { showUpdateMessage = false; } }">Later</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<div class="tool-bar">
|
<div class="tool-bar">
|
||||||
<button class="add" on:click="{ showAdd }"><i class="material-icons">add</i></button>
|
<button class="add" on:click="{ showAdd }"><span class="material-symbols-outlined">add</span></button>
|
||||||
|
{#if updateAvailable}<button class="update"
|
||||||
|
class:animate="{!ignoreUpdate}"
|
||||||
|
on:click={() => { ignoreUpdate = true; showUpdateMessage = !showUpdateMessage; }}><span class="material-symbols-outlined">arrow_upward</span></button>{/if}
|
||||||
<button class="about" on:click="{ () => { showAbout = true; } }">?</button>
|
<button class="about" on:click="{ () => { showAbout = true; } }">?</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -36,6 +44,10 @@ let showAbout = false;
|
||||||
let newCounter = null;
|
let newCounter = null;
|
||||||
let dialogForm = null;
|
let dialogForm = null;
|
||||||
|
|
||||||
|
let updateAvailable = false;
|
||||||
|
let ignoreUpdate = false;
|
||||||
|
let showUpdateMessage = false;
|
||||||
|
|
||||||
function focus(node){
|
function focus(node){
|
||||||
node.focus();
|
node.focus();
|
||||||
}
|
}
|
||||||
|
@ -68,6 +80,10 @@ function add(){
|
||||||
|
|
||||||
showAddDialog = false;
|
showAddDialog = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function SetUpdateAvailable(){
|
||||||
|
updateAvailable = true;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.app {
|
.app {
|
||||||
|
@ -117,8 +133,71 @@ function add(){
|
||||||
border: 2px solid var(--highlight-color);
|
border: 2px solid var(--highlight-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.add {
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
-webkit-text-stroke: 0 rgba(204, 204, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
15% {
|
||||||
|
-webkit-text-stroke: 3px rgba(204, 204, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
30% {
|
||||||
|
-webkit-text-stroke: 0 rgba(204, 204, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.update {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update.animate {
|
||||||
|
animation-name: pulse;
|
||||||
|
animation-duration: 5s;
|
||||||
|
animation-iteration-count: infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.about {
|
.about {
|
||||||
margin-left: auto;
|
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.update-message {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
padding: 12px;
|
||||||
|
|
||||||
|
background-color: var(--background-primary);
|
||||||
|
color: var(--text-primary);
|
||||||
|
|
||||||
|
box-shadow: 0 -1px 3px rgba(0,0,0,0.12), 0 -1px 2px rgba(0,0,0,0.24);
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-message > button {
|
||||||
|
width: auto;
|
||||||
|
height: 24px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(hover: hover){
|
||||||
|
.update-message > button:hover {
|
||||||
|
outline: 2px solid var(--button-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.update-message > button:focus {
|
||||||
|
outline: 2px solid var(--button-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reload {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.later {
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
|
@ -5,14 +5,14 @@
|
||||||
<MyProgress value={ counter.value } max={ counter.max }></MyProgress>
|
<MyProgress value={ counter.value } max={ counter.max }></MyProgress>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<button on:click={ () => { showIncrement = true; } }><i class="material-icons">add</i></button>
|
<button on:click={ () => { showIncrement = true; } }><span class="material-symbols-outlined">add</span></button>
|
||||||
<button on:click={ () => { showSet = true; } }><i class="material-icons">edit</i></button>
|
<button on:click={ () => { showSet = true; } }><span class="material-symbols-outlined">edit</span></button>
|
||||||
<button class="reset" on:click={ reset }><i class="material-icons">replay</i></button>
|
<button class="reset" on:click={ reset }><span class="material-symbols-outlined">replay</span></button>
|
||||||
{#if counter.saveHistory}
|
{#if counter.saveHistory}
|
||||||
<button class="history" on:click={ () => { showHistory = true; } }><i class="material-icons">show_chart</i></button>
|
<button class="history" on:click={ () => { showHistory = true; } }><span class="material-symbols-outlined">show_chart</span></button>
|
||||||
{/if}
|
{/if}
|
||||||
<button on:click={ startEdit }><i class="material-icons">settings</i></button>
|
<button on:click={ startEdit }><span class="material-symbols-outlined">settings</span></button>
|
||||||
<button on:click={ remove }><i class="material-icons">delete</i></button>
|
<button on:click={ remove }><span class="material-symbols-outlined">delete</span></button>
|
||||||
</div>
|
</div>
|
||||||
{#if showValueDialog}
|
{#if showValueDialog}
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
|
@ -47,7 +47,6 @@
|
||||||
<script>
|
<script>
|
||||||
import MyProgress from './MyProgress.svelte';
|
import MyProgress from './MyProgress.svelte';
|
||||||
import History from './History.svelte';
|
import History from './History.svelte';
|
||||||
import { tick } from 'svelte';
|
|
||||||
import { counters } from './db.js';
|
import { counters } from './db.js';
|
||||||
|
|
||||||
export let counterId;
|
export let counterId;
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
<div class="history-container">
|
<div class="history-container">
|
||||||
<header>
|
<header>
|
||||||
<h1>{ counter.title }</h1>
|
<h1>{ counter.title }</h1>
|
||||||
<button class="close" on:click={ close }><i class="material-icons">close</i></button>
|
<button class="close" on:click={ close }><span class="material-symbols-outlined">close</span></button>
|
||||||
</header>
|
</header>
|
||||||
<canvas class="chart-container" bind:this={ chartEl } width="{ window.outerWidth }" height="250">
|
|
||||||
</canvas>
|
|
||||||
<div class="table-container">
|
<div class="table-container">
|
||||||
<table class="history">
|
<table class="history">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -27,7 +25,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
import { counters } from './db.js';
|
import { counters } from './db.js';
|
||||||
import Chart from 'chart.js';
|
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
@ -47,77 +44,9 @@ $: history = counter.history.map(x => {
|
||||||
value: x.value
|
value: x.value
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$: dataset = counter.history.reduce((acc, x) => {
|
|
||||||
return {
|
|
||||||
labels: [...acc.labels, x.time],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
...acc.datasets[0],
|
|
||||||
data: [...acc.datasets[0].data, x.value]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
labels: [],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
borderColor: darkMode ? 'rgba(255, 255, 255, 0.25)' : undefined,
|
|
||||||
backgroundColor: darkMode ? 'rgba(255, 255, 255, 0.25)' : undefined,
|
|
||||||
lineTension: 0.1,
|
|
||||||
data: []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
export let counterId;
|
export let counterId;
|
||||||
|
|
||||||
let chartEl;
|
|
||||||
|
|
||||||
const themeMatch = window.matchMedia('(prefers-color-scheme: dark)');
|
|
||||||
let darkMode = themeMatch.matches;
|
|
||||||
themeMatch.addListener((e) => {
|
|
||||||
darkMode = e.matches;
|
|
||||||
});
|
|
||||||
|
|
||||||
$: {
|
|
||||||
if(chartEl){
|
|
||||||
const theme = darkMode ?
|
|
||||||
{
|
|
||||||
gridLines: {
|
|
||||||
color: 'rgba(255, 255, 255, 0.1)',
|
|
||||||
zeroLineColor: 'rgba(255, 255, 255, 0.25)'
|
|
||||||
},
|
|
||||||
ticks: {
|
|
||||||
fontColor: '#FFFFFF'
|
|
||||||
}
|
|
||||||
} :
|
|
||||||
{} //Use defaults for light mode;
|
|
||||||
|
|
||||||
new Chart(chartEl, {
|
|
||||||
type: 'line',
|
|
||||||
data: dataset,
|
|
||||||
options: {
|
|
||||||
scales: {
|
|
||||||
xAxes: [
|
|
||||||
{
|
|
||||||
...theme,
|
|
||||||
type: 'time'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
yAxes: [
|
|
||||||
{
|
|
||||||
...theme
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
display: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function close(){
|
function close(){
|
||||||
dispatch('close');
|
dispatch('close');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { set as setDb, get as getDb } from 'idb-keyval';
|
import { set as setDb, get as getDb } from 'idb-keyval';
|
||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
import uuid from 'uuid/v4';
|
import { v4 as uuid } from 'uuid';
|
||||||
|
|
||||||
function createCounters(){
|
function createCounters(){
|
||||||
const {subscribe,set,update:updateVal} = writable([]);
|
const {subscribe,set,update:updateVal} = writable([]);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import {registerRoute,setDefaultHandler} from 'workbox-routing';
|
||||||
import {CacheFirst, StaleWhileRevalidate, NetworkFirst} from 'workbox-strategies';
|
import {CacheFirst, StaleWhileRevalidate, NetworkFirst} from 'workbox-strategies';
|
||||||
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
|
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
|
||||||
import {ExpirationPlugin} from 'workbox-expiration';
|
import {ExpirationPlugin} from 'workbox-expiration';
|
||||||
|
import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';
|
||||||
|
|
||||||
// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
|
// Cache the Google Fonts stylesheets with a stale-while-revalidate strategy.
|
||||||
registerRoute(
|
registerRoute(
|
||||||
|
@ -32,6 +33,9 @@ registerRoute(
|
||||||
/\.(?:js|css|png)$/,
|
/\.(?:js|css|png)$/,
|
||||||
new StaleWhileRevalidate({
|
new StaleWhileRevalidate({
|
||||||
cacheName: 'static-resources',
|
cacheName: 'static-resources',
|
||||||
|
plugins: [
|
||||||
|
new BroadcastUpdatePlugin(),
|
||||||
|
],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
const GoogleFontsPlugin = require('@beyonk/google-fonts-webpack-plugin');
|
|
||||||
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
|
||||||
const ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin');
|
|
||||||
const LicensePlugin = require('webpack-license-plugin');
|
const LicensePlugin = require('webpack-license-plugin');
|
||||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||||
|
|
||||||
|
@ -11,27 +9,21 @@ const year = now.getFullYear().toString();
|
||||||
const releaseDate = now.getFullYear() + "-" + (now.getMonth() + 1).toString().padStart(2, '0') + "-" + now.getDate().toString().padStart(2, '0');
|
const releaseDate = now.getFullYear() + "-" + (now.getMonth() + 1).toString().padStart(2, '0') + "-" + now.getDate().toString().padStart(2, '0');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: './src/index.js',
|
entry: {
|
||||||
|
index: './src/index.js',
|
||||||
|
sw: './src/sw.js'
|
||||||
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new CleanWebpackPlugin(),
|
new CleanWebpackPlugin(),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
title: 'NCounter',
|
excludeChunks: ['sw'],
|
||||||
template: 'src/index.html'
|
template: 'src/index.html'
|
||||||
}),
|
}),
|
||||||
new GoogleFontsPlugin({
|
|
||||||
fonts: [
|
|
||||||
{ family: "Material Icons" }
|
|
||||||
],
|
|
||||||
local: false
|
|
||||||
}),
|
|
||||||
new ServiceWorkerWebpackPlugin({
|
|
||||||
entry: path.join(__dirname, 'src/sw.js'),
|
|
||||||
publicPath: './'
|
|
||||||
}),
|
|
||||||
new LicensePlugin(),
|
new LicensePlugin(),
|
||||||
new CopyWebpackPlugin([
|
new CopyWebpackPlugin({
|
||||||
|
patterns: [
|
||||||
{
|
{
|
||||||
from: 'src/icon/*.png', to: 'icons', flatten: true
|
from: 'src/icon/*.png', to: path.resolve(__dirname, 'dist', 'icons', '[name][ext]')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
from: 'src/icon/safari-pinned-tab.svg', to: 'icons'
|
from: 'src/icon/safari-pinned-tab.svg', to: 'icons'
|
||||||
|
@ -45,21 +37,15 @@ module.exports = {
|
||||||
{
|
{
|
||||||
from: 'src/icon/browserconfig.xml', to: 'icons'
|
from: 'src/icon/browserconfig.xml', to: 'icons'
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
|
})
|
||||||
],
|
],
|
||||||
output: {
|
output: {
|
||||||
filename: 'index.js',
|
filename: '[name].js',
|
||||||
path: path.resolve(__dirname, 'dist')
|
path: path.resolve(__dirname, 'dist')
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
|
||||||
test: /\.html$/,
|
|
||||||
loader: 'html-loader',
|
|
||||||
options: {
|
|
||||||
interpolate: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
test: /\.svelte$/,
|
test: /\.svelte$/,
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
|
@ -89,4 +75,7 @@ module.exports = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
resolve: {
|
||||||
|
conditionNames: ['svelte']
|
||||||
|
},
|
||||||
}
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
const merge = require('webpack-merge');
|
const { merge } = require('webpack-merge');
|
||||||
const common = require('./webpack.common.js');
|
const common = require('./webpack.common.js');
|
||||||
|
|
||||||
module.exports = merge(common, {
|
module.exports = merge(common, {
|
||||||
mode: 'development',
|
mode: 'development',
|
||||||
devtool: 'inline-source-map',
|
devtool: 'inline-source-map',
|
||||||
devServer: {
|
devServer: {
|
||||||
contentBase: './dist',
|
static: './dist',
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -1,6 +1,18 @@
|
||||||
const merge = require('webpack-merge');
|
const webpack = require('webpack');
|
||||||
|
const { merge } = require('webpack-merge');
|
||||||
const common = require('./webpack.common.js');
|
const common = require('./webpack.common.js');
|
||||||
|
const Terser = require('terser-webpack-plugin');
|
||||||
|
|
||||||
module.exports = merge(common, {
|
module.exports = merge(common, {
|
||||||
mode: 'production',
|
mode: 'production',
|
||||||
|
plugins: [
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
optimization:{
|
||||||
|
minimizer: [new Terser({
|
||||||
|
test: /\.m?js$/,
|
||||||
|
})]
|
||||||
|
}
|
||||||
});
|
});
|
Loading…
Add table
Add a link
Reference in a new issue