Skip to content
Merged

Next #201

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4708b44
:white_check_mark: Fix Purge testing for removed class
GuiDevloper Mar 31, 2022
9b33589
:sparkles: Add support for webpack custom config
GuiDevloper Mar 31, 2022
fa4ecba
:heavy_minus_sign: :recycle: Move Purge to tests custom config
GuiDevloper Mar 31, 2022
d44770f
:truck: Rename Purge.test to WebpackCustomPlugin
GuiDevloper Apr 1, 2022
2481591
Merge pull request #191 from GuiDevloper/custom-webpack-config
Mortaro Apr 3, 2022
fd0a567
:technologist: Default to cwd() in webpack config
GuiDevloper Apr 15, 2022
0a7c9e5
:label: Avoid declaring Nullstack type & just export
GuiDevloper Apr 15, 2022
bf9cab2
:label: Add types to Nullstack Logo
GuiDevloper Apr 15, 2022
0cc10df
:technologist: Use Node own pkg-resolve for loaders path
GuiDevloper Apr 15, 2022
b4ca0b4
:sparkles: persistent hash
Mortaro Apr 16, 2022
9925fa5
:construction: scriptless index
Mortaro Apr 16, 2022
bb20a5b
:sparkles: read state from meta
Mortaro Apr 16, 2022
0c1c1a5
:wrench: rename webmanifest
Mortaro Apr 16, 2022
0803a86
Merge pull request #193 from GuiDevloper/config-improvements
Mortaro Apr 16, 2022
038859e
Merge pull request #196 from nullstack/persistent-hash
Mortaro Apr 16, 2022
1bdce15
Merge pull request #197 from nullstack/scriptless-index
Mortaro Apr 16, 2022
5d244ca
:label: Use a pattern when typing component props
GuiDevloper Apr 16, 2022
2fdbc5b
Merge pull request #194 from GuiDevloper/types-improvements
Mortaro Apr 16, 2022
17ca95a
:sparkles: add support for named environments
Mortaro Apr 16, 2022
f9afa96
Merge pull request #199 from nullstack/multi-env
Mortaro Apr 17, 2022
ac46c9d
:fire: remove polyfill
Mortaro Apr 18, 2022
2aa745c
Merge pull request #200 from nullstack/remove-polyfill
Mortaro Apr 18, 2022
68715a6
:bookmark: version 0.15.0
Mortaro Apr 18, 2022
21fa5fd
Merge pull request #198 from nullstack/unstable-next
Mortaro Apr 18, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion builders/spa.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = async function spa({ output, cache }) {
await copy('/', '/index.html')
console.log(` ⚙️ /.production/`)
copySync(`${dir}/.production`, path, { filter })
await copy(`/manifest.json`)
await copy(`/manifest.webmanifest`)
await copy(`/service-worker.js`)
await copy('/robots.txt')
console.log()
Expand Down
2 changes: 1 addition & 1 deletion builders/ssg.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ module.exports = async function ssg({ output, cache }) {
await copyRoute()
await copyRoute(`/nullstack/${application.environment.key}/offline`);
await copyRoute(`/404`);
await copyBundle(`/manifest.json`)
await copyBundle(`/manifest.webmanifest`)
await copyBundle(`/service-worker.js`)
await copyBundle('/robots.txt')
await createSitemap()
Expand Down
11 changes: 5 additions & 6 deletions client/context.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import client from './client';
import deserialize from '../shared/deserialize';
import {generateObjectProxy} from './objectProxyHandler';
import { generateObjectProxy } from './objectProxyHandler';
import state from './state';

const context = {};

const memory = deserialize(JSON.stringify(window.context));
for(const key of Object.keys(memory)) {
context[key] = generateObjectProxy(key, memory[key]);
for (const key of Object.keys(state.context)) {
context[key] = generateObjectProxy(key, state.context[key]);
}

const contextProxyHandler = {
Expand All @@ -16,7 +15,7 @@ const contextProxyHandler = {
return true;
},
get(target, name) {
if(name === '_isProxy') return true;
if (name === '_isProxy') return true;
return target[name] === undefined ? context[name] : target[name];
}
}
Expand Down
4 changes: 2 additions & 2 deletions client/environment.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const environment = {...window.environment, client: true, server: false};
//delete window.environment;
import state from './state';
const environment = { ...state.environment, client: true, server: false };

Object.freeze(environment);

Expand Down
8 changes: 4 additions & 4 deletions client/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import deserialize from '../shared/deserialize';
import state from './state'
import element from '../shared/element';
import fragment from '../shared/fragment';
import generateTree from '../shared/generateTree';
Expand All @@ -25,9 +25,9 @@ context.settings = settings;
context.worker = worker;
context.params = params;
context.project = project;
context.environment = window.environment;
context.environment = state.environment;

client.memory = deserialize(JSON.stringify(window.instances));
client.memory = state.instances;

const scope = client;
scope.generateContext = generateContext;
Expand Down Expand Up @@ -73,7 +73,7 @@ export default class Nullstack {
client.nextVirtualDom = null;
}
client.processLifecycleQueues();
delete window.context;
delete state.context;
}, 0)
return generateContext({});
}
Expand Down
9 changes: 5 additions & 4 deletions client/page.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import client from './client';
import windowEvent from './windowEvent';
import state from './state';

const page = {
...window.page,
...state.page,
event: 'nullstack.page'
}

delete window.page;
delete state.page;

const pageProxyHandler = {
set(target, name, value) {
if(name === 'title') {
if (name === 'title') {
document.title = value;
}
const result = Reflect.set(...arguments);
if(name === 'title') {
if (name === 'title') {
windowEvent('page');
}
client.update();
Expand Down
13 changes: 7 additions & 6 deletions client/params.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import router from './router';
import getQueryStringParams from '../shared/getQueryStringParams';
import seserializeParam from '../shared/serializeParam';
import serializeSearch from '../shared/serializeSearch';
import segments, {resetSegments} from './segments';
import segments, { resetSegments } from './segments';
import state from './state';

const paramsProxyHandler = {
set(target, name, value) {
Expand All @@ -13,22 +14,22 @@ const paramsProxyHandler = {
return true;
},
get(target, name) {
if(target[name] === false) return false;
if(segments[name] === false) return false;
if (target[name] === false) return false;
if (segments[name] === false) return false;
return target[name] || segments[name] || '';
}
}

const params = {...window.params};
const params = { ...state.params };

delete window.params;
delete state.params;

const proxy = new Proxy(params, paramsProxyHandler);

export function updateParams(query) {
resetSegments();
const delta = getQueryStringParams(query);
for(const key of Object.keys({...delta, ...params})) {
for (const key of Object.keys({ ...delta, ...params })) {
params[key] = delta[key];
}
return proxy;
Expand Down
6 changes: 4 additions & 2 deletions client/project.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
const project = {...window.project};
import state from './state'

delete window.project;
const project = { ...state.project };

delete state.project;

Object.freeze(project);

Expand Down
6 changes: 4 additions & 2 deletions client/settings.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
const settings = {...window.settings};
delete window.settings;
import state from './state';

const settings = { ...state.settings };
delete state.settings;

Object.freeze(settings);

Expand Down
5 changes: 5 additions & 0 deletions client/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import deserialize from '../shared/deserialize';

const state = deserialize(decodeURI(document.querySelector(`[name=nullstack]`).content));

export default state;
5 changes: 3 additions & 2 deletions client/worker.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import client from './client';
import environment from './environment';
import router from './router';
import state from './state'

const worker = { ...window.worker };
delete window.worker;
const worker = { ...state.worker };
delete state.worker;

const emptyQueue = Object.freeze([]);

Expand Down
6 changes: 5 additions & 1 deletion loaders/register-static-from-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ const traverse = require("@babel/traverse").default;

module.exports = function (source) {
let hasClass = false;
const hash = crypto.createHash('md5').update(source).digest("hex");
const legacyHash = crypto.createHash('md5').update(source).digest("hex");
const id = this.resourcePath.replace(this.rootContext, '')
const hash = crypto.createHash('md5').update(id).digest("hex");
let klassName;
let klassEnd;
const methodNames = [];
Expand Down Expand Up @@ -32,7 +34,9 @@ module.exports = function (source) {
output += source.substring(klassEnd);
for (const methodName of methodNames) {
output += `\nNullstack.registry["${hash}.${methodName}"] = ${klassName}.${methodName};`
output += `\nNullstack.registry["${legacyHash}.${methodName}"] = ${klassName}.${methodName};`
}
output += `\nNullstack.registry["${hash}"] = ${klassName};`
output += `\nNullstack.registry["${legacyHash}"] = ${klassName};`
return output;
}
3 changes: 2 additions & 1 deletion loaders/remove-static-from-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const parse = require('@babel/parser').parse;
const traverse = require("@babel/traverse").default;

module.exports = function removeStaticFromClient(source) {
const hash = crypto.createHash('md5').update(source).digest("hex");
const id = this.resourcePath.replace(this.rootContext, '')
const hash = crypto.createHash('md5').update(id).digest("hex");
let hashPosition;
const injections = {};
const positions = [];
Expand Down
11 changes: 9 additions & 2 deletions logo.njs → logo.nts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
export default function Logo({light, height, monotone}) {
type NullstackLogoProps = {
light?: boolean
monotone?: boolean
duotone?: boolean
height?: string | number
}

export default function Logo({ light, height, monotone }: NullstackLogoProps) {
const themeColor = light ? '#fff' : '#2d3748';
const accentColor = monotone ? themeColor : '#d22365';
return (
Expand Down Expand Up @@ -51,4 +58,4 @@ export default function Logo({light, height, monotone}) {
/>
</svg>
)
}
}
5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nullstack",
"version": "0.14.3",
"version": "0.15.0",
"description": "Full-stack Javascript Components for one-dev armies",
"main": "nullstack.js",
"author": "Mortaro",
Expand Down Expand Up @@ -31,13 +31,10 @@
"dotenv": "^8.2.0",
"express": "^4.17.1",
"fs-extra": "^10.0.0",
"glob": "^7.1.7",
"ignore-loader": "^0.1.2",
"mini-css-extract-plugin": "^2.4.5",
"node-fetch": "2.6.7",
"node-polyfill-webpack-plugin": "^1.1.4",
"nodemon-webpack-plugin": "^4.3.1",
"purgecss-webpack-plugin": "^4.1.3",
"raw-loader": "^4.0.2",
"sass": "^1.32.11",
"sass-loader": "^8.0.2",
Expand Down
17 changes: 14 additions & 3 deletions scripts/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ let lastTrace = '';
let compilingIndex = 1;

const webpack = require('webpack');
const config = require('../webpack.config');
const path = require('path');
const { existsSync } = require('fs');
const customConfig = path.resolve(process.cwd(), './webpack.config.js');
const config = existsSync(customConfig) ? require(customConfig) : require('../webpack.config');

const buildModes = ['ssg', 'spa', 'ssr']

Expand Down Expand Up @@ -47,20 +50,26 @@ function logTrace(stats, showCompiling) {
lastTrace = '';
}

function start({ input, port }) {
function start({ input, port, env }) {
const environment = 'development';
const compiler = getCompiler({ environment, input });
if (port) {
process.env['NULLSTACK_SERVER_PORT'] = port;
}
if (env) {
process.env['NULLSTACK_ENVIRONMENT_NAME'] = env;
}
console.log(` 🚀️ Starting your application in ${environment} mode...`);
console.log();
compiler.watch({}, (error, stats) => logTrace(stats, true));
}

function build({ input, output, cache, mode = 'ssr' }) {
function build({ input, output, cache, env, mode = 'ssr' }) {
const environment = 'production';
const compiler = getCompiler({ environment, input, cache });
if (env) {
process.env['NULLSTACK_ENVIRONMENT_NAME'] = env;
}
console.log(` 🚀️ Building your application in ${mode} mode...`);
compiler.run((error, stats) => {
logTrace(stats, false);
Expand All @@ -75,6 +84,7 @@ program
.description('Start application in development environment')
.option('-p, --port <port>', 'Port number to run the server')
.option('-i, --input <input>', 'Path to project that will be started')
.option('-e, --env <name>', 'Name of the environment file that should be loaded')
.helpOption('-h, --help', 'Learn more about this command')
.action(start)

Expand All @@ -86,6 +96,7 @@ program
.option('-i, --input <input>', 'Path to project that will be built')
.option('-o, --output <output>', 'Path to build output folder')
.option('-c, --cache', 'Cache build results in .production folder')
.option('-e, --env <name>', 'Name of the environment file that should be loaded')
.helpOption('-h, --help', 'Learn more about this command')
.action(build)

Expand Down
9 changes: 9 additions & 0 deletions server/dotenv.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import dotenv from 'dotenv'

let path = '.env'

if (process.env.NULLSTACK_ENVIRONMENT_NAME) {
path += `.${process.env.NULLSTACK_ENVIRONMENT_NAME}`
}

dotenv.config({ path })
2 changes: 2 additions & 0 deletions server/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ environment.mode = process.env.NULLSTACK_ENVIRONMENT_MODE || 'ssr';

environment.key = "{{NULLSTACK_ENVIRONMENT_KEY}}"

environment.name = process.env.NULLSTACK_ENVIRONMENT_NAME || '';

Object.freeze(environment);

export default environment;
2 changes: 1 addition & 1 deletion server/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'dotenv/config';
import './dotenv';
import { normalize } from 'path';
import element from '../shared/element';
import fragment from '../shared/fragment';
Expand Down
22 changes: 11 additions & 11 deletions server/manifest.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {existsSync, readFileSync} from 'fs';
import { existsSync, readFileSync } from 'fs';
import path from 'path';
import project from './project';
import {generateIntegrity} from './integrities';
import { generateIntegrity } from './integrities';
import files from './files';
import {cdn} from './links';
import { cdn } from './links';

export default function generateManifest(server) {
if(files['manifest.json']) return files['manifest.json'];
const file = path.join(__dirname, '../', 'public', 'manifest.json');
if(existsSync(file)) {
if (files['manifest.webmanifest']) return files['manifest.webmanifest'];
const file = path.join(__dirname, '../', 'public', 'manifest.webmanifest');
if (existsSync(file)) {
return readFileSync(file, 'utf-8');
}
const json = {
Expand All @@ -20,10 +20,10 @@ export default function generateManifest(server) {
"orientation": project.orientation,
"scope": project.scope,
"start_url": project.root,
"icons": [],
"icons": [],
"splash_pages": null
}
for(const size in project.icons) {
for (const size in project.icons) {
const icon = project.icons[size];
json.icons.push({
"src": cdn(icon),
Expand All @@ -33,9 +33,9 @@ export default function generateManifest(server) {
});
}
const manifest = JSON.stringify(json);
if(!server.less) {
generateIntegrity('manifest.json', manifest);
if (!server.less) {
generateIntegrity('manifest.webmanifest', manifest);
}
files['manifest.json'] = manifest;
files['manifest.webmanifest'] = manifest;
return manifest;
}
Loading