tweak resources loading

This commit is contained in:
Pig Fang 2020-05-18 16:40:31 +08:00
parent 50502baea7
commit 907d370b19
32 changed files with 322 additions and 1662 deletions

View File

@ -2,11 +2,12 @@
namespace App\Http\Controllers;
use App\Services\Webpack;
use Illuminate\Support\Arr;
class HomeController extends Controller
{
public function index()
public function index(Webpack $webpack)
{
return view('home')
->with('user', auth()->user())
@ -15,6 +16,11 @@ class HomeController extends Controller
->with('fixed_bg', option('fixed_bg'))
->with('hide_intro', option('hide_intro'))
->with('home_pic_url', option('home_pic_url') ?: config('options.home_pic_url'))
->with('home_page_css', $webpack->url('home.css'))
->with(
'home_page_css_loader',
config('app.asset.env') === 'development' ? $webpack->url('home.js') : null
)
->with('user_can_register', option('user_can_register'));
}

View File

@ -46,22 +46,38 @@ class FootComposer
$scripts = [];
$locale = app()->getLocale();
$scripts[] = $this->javascript->generate($locale);
$scripts[] = [
'src' => $this->javascript->generate($locale),
'defer' => true,
];
if ($pluginI18n = $this->javascript->plugin($locale)) {
$scripts[] = $pluginI18n;
$scripts[] = [
'src' => $pluginI18n,
'defer' => true,
];
}
if (Str::startsWith(config('app.asset.env'), 'dev')) {
$scripts[] = $this->webpack->url('style.js');
$scripts[] = [
'src' => $this->webpack->url('style.js'),
'async' => true,
'defer' => true,
];
} else {
$scripts[] = 'https://cdn.jsdelivr.net/combine/'.
$scripts[] = [
'src' => 'https://cdn.jsdelivr.net/combine/'.
'npm/react@16.13/umd/react.production.min.js,'.
'npm/react-dom@16.13/umd/react-dom.production.min.js,'.
'npm/jquery@3.4,'.
'npm/popper.js@1.16,'.
'npm/bootstrap@4.4/dist/js/bootstrap.min.js,'.
'npm/admin-lte@3.0';
'npm/react-dom@16.13/umd/react-dom.production.min.js',
'crossorigin' => 'anonymous',
];
}
$scripts[] = $this->webpack->url('app.js');
$scripts[] = [
'src' => 'https://cdn.jsdelivr.net/npm/@blessing-skin/admin-lte@3.0/dist/admin-lte.min.js',
'integrity' => 'sha256-lEpMZPtZ0RgHYZFOcJeX94WMegvHJ+beF5V7XtCcWxY=',
'crossorigin' => 'anonymous',
];
$scripts[] = [
'src' => $this->webpack->url('app.js'),
];
$view->with([
'scripts' => $scripts,

View File

@ -73,10 +73,40 @@ class HeadComposer
public function injectStyles(View $view)
{
$view->with('styles', [
$this->webpack->url('style.css'),
'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/css/all.min.css',
]);
$links = [];
$links[] = [
'rel' => 'stylesheet',
'href' => 'https://cdn.jsdelivr.net/npm/@blessing-skin/admin-lte@3.0.4/dist/admin-lte.min.css',
'integrity' => 'sha256-nr8InsK/i0Skb3n3yHCVwEnsmblkae4Rs9aFJ4/JTWE=',
'crossorigin' => 'anonymous',
];
$links[] = [
'rel' => 'preload',
'as' => 'font',
'href' => 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/webfonts/fa-solid-900.woff2',
'integrity' => 'sha256-f00/0KcF2/hAMpiq2R1d5pcua11TYGjrqLJJVKWgqMc=',
'crossorigin' => 'anonymous',
];
$links[] = [
'rel' => 'preload',
'as' => 'font',
'href' => 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/webfonts/fa-regular-400.woff2',
'integrity' => 'sha256-aoyOnh5/aSwhrxlW3hY/PQJneOZEn+k6CaZxhHyhrmU=',
'crossorigin' => 'anonymous',
];
$links[] = [
'rel' => 'stylesheet',
'href' => 'https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.0/css/all.min.css',
'integrity' => 'sha256-h20CPZ0QyXlBuAw7A+KluUYx/3pK+c7lYEpqLTlxjYQ=',
'crossorigin' => 'anonymous',
];
$links[] = [
'rel' => 'preload',
'as' => 'script',
'href' => $this->webpack->url('app.js'),
];
$links[] = ['rel' => 'stylesheet', 'href' => $this->webpack->url('style.css')];
$view->with('links', $links);
$view->with('inline_css', option('custom_css'));
}

View File

@ -22,7 +22,6 @@
"@fortawesome/fontawesome-free": "^5.12.0",
"@hot-loader/react-dom": "^16.11.0",
"@tweenjs/tween.js": "^18.4.2",
"admin-lte": "^3.0.1",
"blessing-skin-shell": "^0.3.1",
"cli-spinners": "^2.2.0",
"commander": "^5.0.0",
@ -63,7 +62,9 @@
"@typescript-eslint/eslint-plugin": "^2.8.0",
"@typescript-eslint/parser": "^2.8.0",
"autoprefixer": "^9.7.3",
"bootstrap": "^4.5.0",
"css-loader": "^3.4.2",
"cssnano": "^4.1.10",
"eslint": "^6.7.1",
"eslint-config-gplane": "^6.2.1",
"eslint-formatter-beauty": "^3.0.0",
@ -72,14 +73,9 @@
"jest-extended": "^0.11.5",
"js-yaml": "^3.13.1",
"mini-css-extract-plugin": "^0.9.0",
"optimize-css-assets-webpack-plugin": "^5.0.3",
"postcss-loader": "^3.0.0",
"prettier": "^2.0.1",
"sass": "^1.25.0",
"sass-loader": "^8.0.2",
"style-loader": "^1.1.2",
"stylus": "^0.54.7",
"stylus-loader": "^3.0.2",
"ts-jest": "^25.2.1",
"ts-loader": "^7.0.4",
"typescript": "^3.9.2",
@ -193,7 +189,7 @@
"node"
],
"moduleNameMapper": {
"\\.(s?css|styl)$": "<rootDir>/resources/assets/tests/__mocks__/style.ts",
"\\.css$": "<rootDir>/resources/assets/tests/__mocks__/style.ts",
"\\.(png|jpg)$": "<rootDir>/resources/assets/tests/__mocks__/file.ts",
"^@/(.*)$": "<rootDir>/resources/assets/src/$1"
},

View File

@ -1,6 +1,7 @@
/* eslint-disable global-require */
module.exports = {
plugins: [
require('cssnano')(),
require('autoprefixer'),
],
}

View File

@ -1,6 +1,4 @@
import './init' // Must be first
import 'bootstrap'
import 'admin-lte'
import './i18n'
import './net'
import './event'

View File

@ -1,8 +1,6 @@
/* eslint-disable prefer-const */
/* eslint-disable @typescript-eslint/camelcase */
import $ from 'jquery'
// @ts-ignore
declare let __webpack_public_path__: string
@ -13,6 +11,3 @@ __webpack_public_path__ =
process.env.NODE_ENV === 'development'
? url.toString()
: `${blessing.base_url}/app/`
// @ts-ignore
window.$ = window.jQuery = $ // eslint-disable-line

View File

@ -3,7 +3,7 @@ import React from 'react'
export default [
{
path: '/',
module: [() => import('../styles/home.styl'), () => import('./home-page')],
module: [() => import('./home-page')],
},
{
path: 'user',

View File

@ -1,11 +0,0 @@
@import '~bootstrap/scss/functions';
@import '~admin-lte/build/scss/bootstrap-variables';
@import '~bootstrap/scss/bootstrap';
@import '~admin-lte/build/scss/variables';
@import '~admin-lte/build/scss/mixins';
@import '~admin-lte/build/scss/parts/core';
@import '~admin-lte/build/scss/parts/miscellaneous';
@import '~admin-lte/build/scss/parts/components';
@import '~admin-lte/build/scss/small-box';
@import '~admin-lte/build/scss/info-box';
@import '~admin-lte/build/scss/pages/login_and_register';

View File

@ -0,0 +1,10 @@
#chart {
width: 100%;
height: 400px;
}
.btn-color {
width: 40px;
height: 20px;
cursor: pointer;
}

View File

@ -1,12 +0,0 @@
.btn-edit
font-size 12px
color #367fa9
#chart
width 100%
height 400px
.btn-color
width 40px
height 20px
cursor pointer

View File

@ -0,0 +1,8 @@
.login-logo a {
font-family: Minecraft;
transition: all 0.2s ease-in-out;
}
.login-logo a:hover {
color: #42a5f5;
}

View File

@ -1,5 +0,0 @@
.login-logo a
font-family Minecraft, 'Segoe UI', 'Microsoft Yahei', sans-serif
transition all 0.2s ease-in-out
&:hover
color #42a5f5

View File

@ -0,0 +1,21 @@
@import '../fonts/minecraft.css';
@import './avatar.css';
@import './dropdown.css';
@import './auth.css';
@import './admin.css';
a {
outline: none;
}
.brand-link, .navbar-brand {
font-family: Minecraft;
}
.breadcrumb {
font-size: 14px;
}
.user-panel .info {
cursor: default;
}

View File

@ -1,10 +0,0 @@
@import './avatar';
@import './dropdown';
a {
outline: none;
}
.cursor-pointer {
cursor: pointer;
}

View File

@ -1,15 +0,0 @@
@import './auth'
@import './admin'
@font-face
font-family 'Minecraft'
src url('../fonts/minecraft.woff2') format('woff2'), url('../fonts/minecraft.woff') format('woff')
.brand-link, .navbar-brand
font-family Minecraft
.breadcrumb
font-size 14px
.user-panel .info
cursor default

View File

@ -0,0 +1,14 @@
.dropdown-item:hover,
.dropdown-item:focus {
color: #fff;
background-color: var(--blue);
}
.dropdown-item.dropdown-item-danger {
color: var(--danger);
}
.dropdown-item.dropdown-item-danger:hover,
.dropdown-item.dropdown-item-danger:focus {
color: #fff;
background-color: var(--danger);
}

View File

@ -1,15 +0,0 @@
.dropdown-item {
&:hover, &:focus {
color: #fff;
background-color: var(--blue);
}
&.dropdown-item-danger {
color: var(--danger);
&:hover, &:focus {
color: #fff;
background-color: var(--danger);
}
}
}

View File

@ -0,0 +1,118 @@
body {
font-size: 16px;
}
.layout-top-nav > .hp-wrapper {
background-size: cover;
background-repeat: no-repeat;
background-position: center 0;
height: 100vh;
}
.navbar {
transition: color 0.25s ease-in-out, border-color 0.25s ease-in-out,
background-color 0.25s ease-in-out;
}
.navbar.transparent {
background-color: rgba(255, 255, 255, 0.2);
}
.navbar.transparent .navbar-brand {
color: #5e5e5e;
}
.navbar-brand {
font-family: Minecraft;
}
.splash {
width: 80%;
height: 50%;
margin: auto;
position: absolute;
top: 100px;
left: 0;
bottom: 0;
right: 0;
text-align: center;
}
.splash-head {
color: #fff;
padding: 0.8em 0.5em 1em;
line-height: 1.5em;
margin: 0.2em 0 0.5em;
font-family: Minecraft;
text-shadow: 0 4px 3px rgba(0, 0, 0, 0.4), 0 8px 13px rgba(0, 0, 0, 0.1),
0 18px 23px rgba(0, 0, 0, 0.1);
}
.splash-subhead {
font-size: 16px;
letter-spacing: 0.05em;
margin-bottom: 3em;
color: #fff;
font-family: Ubuntu, 'Segoe UI', 'Microsoft Yahei', 'Microsoft Jhenghei',
sans-serif;
}
@media (max-width: 768px) {
.splash {
width: 100%;
}
.splash-head {
font-size: 200%;
}
}
@media (min-width: 768px) {
.splash-head {
font-size: 250%;
}
}
.main-button {
color: #fff;
padding: 0.8em 2.5em;
border-radius: 5px;
background: transparent;
border: 1px solid #fff;
font-size: 120%;
transition: color 0.25s ease-in-out, border-color 0.25s ease-in-out,
background-color 0.25s ease-in-out;
}
.main-button:hover {
color: #fff;
background-color: rgba(255, 255, 255, 0.2);
}
#fixed-bg {
position: fixed;
z-index: -1;
height: 100vh;
width: 100%;
background-size: cover;
}
#intro {
padding: 50px 0;
border-top: 5px solid #bdc3c7;
background-color: #fff;
}
#intro i {
font-size: 80px;
}
#footer-wrap {
color: #fff;
background-color: #2f2f2f;
padding: 50px 0;
}
#copyright {
color: #fff;
}
#copyright.with-intro {
background-color: #222;
padding: 15px 0;
}
#copyright.without-intro {
position: fixed;
bottom: 0;
width: 100%;
padding: 16px 50px;
}

View File

@ -1,147 +0,0 @@
body
font-size 16px
.layout-top-nav > .hp-wrapper
// background image settings
background-size cover
background-repeat no-repeat
background-position center 0
height 100vh
.navbar-brand
font-family Minecraft, 'Segoe UI', 'Microsoft Yahei', 'Microsoft Jhenghei', sans-serif
.navbar
transition color 0.25s ease-in-out, border-color 0.25s ease-in-out, background-color 0.25s ease-in-out
.transparent
.navbar-brand
color #5e5e5e
&.navbar
background-color rgba(255, 255, 255, 0.2)
.splash
width 80%
height 50%
margin auto
position absolute
top 100px
left 0
bottom 0
right 0
text-align center
.splash-head
font-size 20px
font-weight bold
color white
padding 0.8em 0.5em 1em
font-weight 100
line-height 1.5em
margin 0.2em 0 0.5em
font-family Minecraft, 'Segoe UI', 'Microsoft Yahei', 'Microsoft Jhenghei', sans-serif !important
text-shadow 0px 4px 3px rgba(0, 0, 0, 0.4), 0px 8px 13px rgba(0, 0, 0, 0.1), 0px 18px 23px rgba(0, 0, 0, 0.1)
.splash-subhead
font-size 16px
letter-spacing 0.05em
margin-bottom 3em
color #fff
font-family Ubuntu, 'Segoe UI', 'Microsoft Yahei', 'Microsoft Jhenghei', sans-serif
/* Mobile phone */
@media (max-width: 48em)
.splash-head
font-size 200%
.splash
width 100%
height 50%
@media (min-width: 48em)
.splash
width 80%
height 50%
.splash-head
font-size 250%
@media (min-width: 64em)
.splash-head
font-size 300%
.button
color white
padding 0.8em 2.5em
border-radius 5px
background transparent
border 1px solid #fff
font-size 120%
transition color 0.25s ease-in-out, border-color 0.25s ease-in-out, background-color 0.25s ease-in-out
.button:hover
color white
background-color rgba(255, 255, 255, 0.2)
hr
display block
height 1px
border 0
border-top 1px solid #ccc
margin 1em 0
padding 0
.hp-wrapper
width 100%
#fixed-bg
position fixed
z-index -1
height 100vh
width 100%
background-size cover
/* ==========================================================================
Wrap Sections
========================================================================== */
/* intro Wrap */
#intro
padding 50px 0 50px
border-top #bdc3c7 solid 5px
background-color white
i
font-size 80px
.col-lg-4
margin 10px 0 50px
@media (min-width: 1200px)
.col-lg-4
margin 10px 0 20px
#footerwrap
background-color #2f2f2f
color white
padding 40px 0 50px
text-align left
.col-lg-6:last-child
text-align center
padding-top 50px
@media (min-width: 1200px)
.col-lg-6:last-child
text-align right
padding-top 20px
#copyright
color #fff
&.with-intro
background #222
padding 16px 0 20px
&.without-intro
position fixed
bottom 0
width 100%
padding 0 50px 16px 50px

View File

@ -1,11 +1,5 @@
import { css } from '@emotion/core'
export const truncateText = css`
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
`
export const pointerCursor = css`
cursor: pointer;
`

View File

@ -1,8 +1,6 @@
/** @jsx jsx */
import { jsx } from '@emotion/core'
import React from 'react'
import styled from '@emotion/styled'
import { t } from '@/scripts/i18n'
import * as cssUtils from '@/styles/utils'
import { Plugin } from './types'
const Box = styled.div`
@ -34,7 +32,6 @@ const Header = styled.div`
`
const Description = styled.div`
font-size: 14px;
${cssUtils.truncateText};
`
interface Props {
@ -79,7 +76,7 @@ const InfoBox: React.FC<Props> = (props) => {
}
onChange={handleChange}
/>
<strong className="d-inline-block mr-2" css={cssUtils.truncateText}>
<strong className="d-inline-block mr-2 text-truncate">
{plugin.title}
</strong>
<span className="d-none d-sm-inline-block text-gray">
@ -112,7 +109,7 @@ const InfoBox: React.FC<Props> = (props) => {
</ActionButton>
</div>
</div>
<Description className="mt-2" title={plugin.description}>
<Description className="mt-2 text-truncate" title={plugin.description}>
{plugin.description}
</Description>
</div>

View File

@ -1,9 +1,7 @@
/** @jsx jsx */
import { jsx } from '@emotion/core'
import React from 'react'
import styled from '@emotion/styled'
import { t } from '@/scripts/i18n'
import { Texture } from '@/scripts/types'
import * as cssUtils from '@/styles/utils'
import { Report, Status } from './types'
const Card = styled.div`
@ -119,7 +117,7 @@ const ImageBox: React.FC<Props> = (props) => {
(UID: {report.reporter})
</div>
<details>
<summary css={cssUtils.truncateText}>
<summary className="text-truncate">
<b>
{t('report.reason')}
{': '}

View File

@ -1,5 +1,3 @@
/** @jsx jsx */
import { jsx } from '@emotion/core'
import React, { useState, useEffect } from 'react'
import { createPortal } from 'react-dom'
import { hot } from 'react-hot-loader/root'
@ -11,7 +9,6 @@ import { showModal, toast } from '@/scripts/notify'
import { Texture, TextureType } from '@/scripts/types'
import ButtonEdit from '@/components/ButtonEdit'
import ViewerSkeleton from '@/components/ViewerSkeleton'
import * as cssUtils from '@/styles/utils'
import ModalApply from '@/views/user/Closet/ModalApply'
import removeClosetItem from '@/views/user/Closet/removeClosetItem'
import setAsAvatar from '@/views/user/Closet/setAsAvatar'
@ -337,11 +334,7 @@ const Show: React.FC = () => {
<div className="container">
<div className="row mt-2 mb-4">
<div className="col-4">{t('skinlib.show.name')}</div>
<div
className="col-7"
css={cssUtils.truncateText}
title={texture.name}
>
<div className="col-7 text-truncate" title={texture.name}>
{texture.name}
</div>
{canEdit && (
@ -371,11 +364,7 @@ const Show: React.FC = () => {
</div>
<div className="row my-4">
<div className="col-4">Hash</div>
<div
className="col-8"
css={cssUtils.truncateText}
title={texture.hash}
>
<div className="col-8 text-truncate" title={texture.hash}>
{texture.hash}
</div>
</div>
@ -385,7 +374,7 @@ const Show: React.FC = () => {
</div>
<div className="row my-4">
<div className="col-4">{t('skinlib.show.uploader')}</div>
<div className="col-8" css={cssUtils.truncateText}>
<div className="col-8 text-truncate">
{isUploaderExists ? (
<React.Fragment>
<div>

View File

@ -71,8 +71,7 @@ const Item: React.FC<Props> = (props) => {
</div>
<div className="card-footer">
<a
className="d-block mb-1"
css={cssUtils.truncateText}
className="d-block mb-1 truncate-text"
title={item.name}
href={link}
target="_blank"
@ -85,7 +84,8 @@ const Item: React.FC<Props> = (props) => {
{humanizeType(item.type)}
</span>
<a
className="badge bg-indigo py-1 cursor-pointer"
className="badge bg-indigo py-1"
css={cssUtils.pointerCursor}
title={t('skinlib.show.uploader')}
onClick={handleUploaderClick}
>

View File

@ -1,10 +1,7 @@
/** @jsx jsx */
import React from 'react'
import { jsx, css } from '@emotion/core'
import styled from '@emotion/styled'
import { t } from '@/scripts/i18n'
import { ClosetItem } from '@/scripts/types'
import * as cssUtils from '@/styles/utils'
import setAsAvatar from './setAsAvatar'
const Card = styled.div`
@ -20,7 +17,7 @@ const Card = styled.div`
background-color: #eff1f0;
}
`
const blackOnHover = css`
const DropdownButton = styled.i`
:hover {
color: #000;
}
@ -54,7 +51,7 @@ const ClosetItem: React.FC<Props> = (props) => {
</div>
<div className="card-footer pb-2 pt-2 pl-1 pr-1">
<div className="container d-flex justify-content-between">
<span css={cssUtils.truncateText} title={item.pivot.item_name}>
<span className="text-truncate" title={item.pivot.item_name}>
{item.pivot.item_name}
</span>
<span className="d-inline-block drop-down">
@ -63,7 +60,7 @@ const ClosetItem: React.FC<Props> = (props) => {
aria-haspopup="true"
aria-expanded="false"
>
<i className="fas fa-cog text-gray" css={blackOnHover} />
<DropdownButton className="fas fa-cog text-gray" />
</span>
<div className="dropdown-menu">
<a href="#" className="dropdown-item" onClick={props.onRename}>

View File

@ -2,6 +2,8 @@
<html lang="{{ locale }}">
<head>
{{ include('shared.head') }}
<link rel="stylesheet" href="{{ home_page_css }}">
<link rel="preload" as="image" href="{{ home_pic_url }}">
<title>{{ site_name }}</title>
<style>
.hp-wrapper {
@ -59,16 +61,16 @@
</p>
<p>
{% if auth_check() %}
<a href="{{ url('user') }}" class="button">
<a href="{{ url('user') }}" class="main-button">
{{ trans('general.user-center') }}
</a>
{% else %}
{% if user_can_register %}
<a href="{{ url('auth/register') }}" class="button">
<a href="{{ url('auth/register') }}" class="main-button">
{{ trans('general.register') }}
</a>
{% else %}
<a href="{{ url('auth/login') }}" class="button">
<a href="{{ url('auth/login') }}" class="main-button">
{{ trans('general.login') }}
</a>
{% endif %}
@ -108,7 +110,7 @@
<br>
</div>
</div>
<div id="footerwrap">
<div id="footer-wrap">
<div class="container">
<div class="row">
<div class="col-lg-6 mb-2">
@ -116,7 +118,7 @@
</div>
<div class="col-lg-4"></div>
<div class="col-lg-2 d-flex justify-content-center align-items-center">
<a href="{{ url('auth/register') }}" class="button">
<a href="{{ url('auth/register') }}" class="main-button">
{{ trans('index.start') }}
</a>
</div>
@ -130,6 +132,9 @@
</div>
{% endif %}
{% if home_page_css_loader %}
<script src="{{ home_page_css_loader }}"></script>
{% endif %}
<script>
blessing.extra = { transparent_navbar: {{ transparent_navbar ? 'true' : 'false' }} }
</script>

View File

@ -1,5 +1,5 @@
{% for script in scripts %}
<script src="{{ script }}"></script>
<script{% for attribute, value in script %} {{ attribute }}="{{ value }}"{% endfor %}></script>
{% endfor %}
<script>

View File

@ -6,13 +6,11 @@
<meta name="keywords" content="{{ seo.keywords }}">
<meta name="description" content="{{ seo.description }}">
{{ seo.extra|striptags('<meta>')|raw }}
{% for link in links %}
<link{% for attribute, value in link %} {{ attribute }}="{{ value }}"{% endfor %}>
{% endfor %}
<link rel="shortcut icon" href="{{ favicon }}">
<link rel="icon" type="image/png" href="{{ favicon }}" sizes="192x192">
<link rel="apple-touch-icon" href="{{ favicon }}" sizes="180x180">
{% for style in styles %}
<link rel="stylesheet" href="{{ style }}">
{% endfor %}
<style>{{ inline_css|striptags }}</style>
{{ extra_head|join('\n')|raw }}

View File

@ -2,7 +2,6 @@ const path = require('path')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const ManifestPlugin = require('webpack-manifest-plugin')
const devMode = !process.argv.includes('-p')
@ -12,11 +11,8 @@ const config = {
mode: devMode ? 'development' : 'production',
entry: {
app: ['react-hot-loader/patch', '@/index.tsx'],
style: [
'@/styles/admin-lte.scss',
'@/styles/common.styl',
'@/styles/common.scss',
],
style: ['@/styles/common.css'],
home: '@/styles/home.css',
spectre: [
'spectre.css/dist/spectre.min.css',
'@/fonts/minecraft.css',
@ -38,55 +34,17 @@ const config = {
transpileOnly: true,
},
},
{
test: /\.scss$/,
exclude: /\.module\.scss$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2,
},
},
'postcss-loader',
'sass-loader',
],
},
{
test: /\.module\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
modules: {
localIdentName: devMode
? '[name]__[local]'
: '[local]__[hash:base64:5]',
},
esModule: true,
},
},
'postcss-loader',
'sass-loader',
],
},
{
test: /\.css$/,
use: [
devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
'css-loader',
],
},
{
test: /(common|home)\.styl$/,
use: [
MiniCssExtractPlugin.loader,
{ loader: 'css-loader', options: { importLoaders: 2 } },
loader: 'css-loader',
options: {
importLoaders: 1,
},
},
'postcss-loader',
'stylus-loader',
],
},
{
@ -113,20 +71,20 @@ const config = {
alias: {
'react-dom': '@hot-loader/react-dom',
'@': path.resolve(__dirname, 'resources/assets/src'),
'readline': '@/scripts/cli/readline.ts',
readline: '@/scripts/cli/readline.ts',
},
},
externals: devMode
externals: Object.assign(
{ jquery: 'jQuery', bootstrap: 'bootstrap', 'admin-lte': 'adminlte' },
devMode
? {}
: {
react: 'React',
'react-dom': 'ReactDOM',
jquery: 'jQuery',
bootstrap: 'bootstrap',
'admin-lte': 'adminlte',
},
),
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
minimizer: [new TerserJSPlugin({})],
},
devtool: devMode ? 'cheap-module-eval-source-map' : false,
devServer: {

1336
yarn.lock

File diff suppressed because it is too large Load Diff