Perhaps you want to learn about how to make a 404 page with Nullstack?
-If you are looking for something else, you should read the documentation.
-diff --git a/.env b/.env
new file mode 100644
index 00000000..fefc515a
--- /dev/null
+++ b/.env
@@ -0,0 +1 @@
+NULLSTACK_SERVER_PORT=5000
\ No newline at end of file
diff --git a/.github/workflows/ssg-build.yml b/.github/workflows/ssg-build.yml
new file mode 100644
index 00000000..f32d4a95
--- /dev/null
+++ b/.github/workflows/ssg-build.yml
@@ -0,0 +1,42 @@
+# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
+
+name: SSG Build to Deploy
+
+on:
+ push:
+ branches: [ master ]
+ workflow_dispatch:
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ # cache the dependencies from any node_modules directory
+ - name: Cache dependencies
+ uses: actions/cache@v2
+ with:
+ path: |
+ **/node_modules
+ **/package-lock.json
+ **/.production
+ key: node_modules-${{ hashFiles('**/package.json') }}
+
+ - name: Install deps
+ run: npm install
+
+ - name: Build
+ run: npx nullstack build --mode=ssg --output=docs
+
+ - name: Send to Github
+ run: |
+ git branch gh-pages -f
+ git checkout gh-pages
+ touch ./docs/.nojekyll
+ git add docs -f
+ git config --global user.name "NullstackDeployer"
+ git config --global user.email "nullstack@deployer.ci"
+ git commit -m ":rocket: New SSG Build"
+ git push -u origin gh-pages -f
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 9792703c..81cf24c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,7 @@ node_modules
package-lock.json
yarn.lock
.development
-.production
\ No newline at end of file
+.production
+public/pt-BR.json
+public/en-US.json
+docs
diff --git a/README.br.md b/README.br.md
new file mode 100644
index 00000000..2ff90cac
--- /dev/null
+++ b/README.br.md
@@ -0,0 +1,21 @@
+# Documentação do Nullstack
+
+
+
+## Como executar este projeto
+
+Instale as dependências:
+
+`npm install`
+
+Rode a aplicação no modo de desenvolvimento:
+
+`npm start`
+
+Abra [http://localhost:5000](http://localhost:5000) para vê-lo no navegador.
+
+## Aprenda mais sobre o Nullstack
+
+[Leia a documentação](https://nullstack.app/pt-br/comecando)
+
+ Read in English
\ No newline at end of file
diff --git a/README.md b/README.md
index f6b6edc1..196e83fb 100644
--- a/README.md
+++ b/README.md
@@ -16,4 +16,6 @@ Open [http://localhost:5000](http://localhost:5000) to view it in the browser.
## Learn more about Nullstack
-[Read the documentation](https://nullstack.app/documentation)
\ No newline at end of file
+[Read the documentation](https://nullstack.app/getting-started)
+
+ Leia em Português
\ No newline at end of file
diff --git a/client.js b/client.js
new file mode 100644
index 00000000..e251a2a3
--- /dev/null
+++ b/client.js
@@ -0,0 +1,6 @@
+import Nullstack from "nullstack";
+import Application from "./src/Application";
+
+const context = Nullstack.start(Application);
+
+export default context
\ No newline at end of file
diff --git a/docs/404.html b/docs/404.html
deleted file mode 100644
index fd10b8e2..00000000
--- a/docs/404.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
Perhaps you want to learn about how to make a 404 page with Nullstack?
-If you are looking for something else, you should read the documentation.
-Perhaps you want to learn about how to make a 404 page with Nullstack?
-If you are looking for something else, you should read the documentation.
-Perhaps you want to learn about how to make a 404 page with Nullstack?
\nIf you are looking for something else, you should read the documentation.
\n","description":"Sorry, this is not the page you are looking for.","status":404},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":404,"title":"Page Not Found - Nullstack","description":"Sorry, this is not the page you are looking for."}} \ No newline at end of file diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index e242231c..00000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -nullstack.app \ No newline at end of file diff --git a/docs/about.html b/docs/about.html deleted file mode 100644 index eaf89507..00000000 --- a/docs/about.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - -The sole purpose of Nullstack is to simplify the development by eliminating glue code and letting you focus on the logic of your application.
-It was created keeping in mind programmers used to developing entire systems alone, but it is easily scalable to small or even big teams, as long as each programmer knows the flow of the feature they are to develop.
-With the stack of technologies used in the web nowadays, the most common flow is something like this:
-Note that all you wanted was to show something from the database into a view. With Nullstack, that’s all you need to concern yourself with. Everything else is “glue code” and the framework should take care of it for you.
-If you’re used to working on more than one project at a time or even if you just happen to have to give sporadic maintenance to a lot of your old projects, you might have stumbled upon this scenario: you don’t remember exactly where in your code is the logic you’re trying to fix or improve.
-You might have a hook whose dependencies are local variables initialized with a redux state, which was stored at some point by an action declared somewhere in your source tree and called in who knows where.
-If everything pertaining to a single feature were to be in the same file, maybe you wouldn’t need to reverse engineer your own code every time you need to update or fix something.
-Putting everything in a single file may sound messy at a glance, but remember that you are the one who decides the granularity of this division.
-A "feature" might be an entire register form or something as small as a button that does some verifications before letting you submit that form. It’s entirely up to you, and since each component is as complete as an entire feature, you could call this button or even the entire form on other pages in your application. This leads us to True Componentization and Code Reusability.
-Components in Nullstack are self-sufficient.
-Most frameworks are specialized in a single layer, meaning that any component will be only as complete as its framework. When exporting a Nullstack component, all the code needed to run the feature is going to be together, without the need of allocating the other layers separately.
-As a side effect, entire applications can be used as components, and mounted in other applications as engines.
-At first glance, classes may look more verbose than the trendy functional components. -This section will explain the reasons that lead us to favor classes in the development of Nullstack.
-The reasons are actually connected to some core principles of Nullstack, being:
-We didn’t want to introduce a “Nullstack way” of doing things and wanted it to be accessible to anyone with some Javascript knowledge.
-That being said, the first big problem was to address state management in a vanilla Javascript way. Supporting functional components would require a solution similar to the hooks of React.js that would be considered a mannerism of the framework.
-Since we opted out of immutability as a framework constraint, we are allowed to use the native way of setting simple variables. This removes the complexity of state management that created the need of third-party state management libraries in the first place.
-Nullstack borrows the concept of “battery-included” from Ember.js, but allows you to change batteries. Everything you need to make an application should be part of the framework, and still be flexible.
-A framework should do the heavy lifting and a programmer should focus on his own application. -For this reason, all you have to do is to declare your classes and let Nullstack instantiate them for you. That way, we removed the most painful aspect of dealing with classes while maintaining all of the advantages of them.
-Object-oriented versus functional is not a new topic, and lately the former seems to be bullied out of most frameworks, leaving no place for developers that enjoy this pattern.
-Admittedly classes took too long to be standardized into Javascript and the delay might have caused some traumatic bad implementations along the way.
-While object-oriented programming might not be the best solution for every problem, Nullstack allows you to import functions freely and use them in the moments when they should be the weapon of choice.
-Nullstack context uses the dependency injection pattern, which means that everything you need can be requested from the framework at the signature level of the function.
-The context is a horizontally scoped object that is injected in all of your function calls. The non-hierarchical nature of this pattern allows you to easily move around your component's logic as your application grows, while still avoiding problems like props drilling or filling your view layer with store declarations.
-This has two major advantages:
-You see the dependencies of your code at a function level instead of having them all imported on top of the file.
The framework is able to give you the most precise information about the specific environment for that function call.
The generated application is enough to have a PWA without thinking about boilerplates, but you are completely free to override the default behavior of each moving piece.
-A borrowed concept from Ruby is developer happiness. Nullstack aims to ease the developer’s life by simplifying everything possible, but without hiding things from you.
-The first developers we wanted to make happy are ourselves. We made Nullstack because we had fun in the process. It started as a simple prototype on top of React.js and we got carried away, each time making it more enjoyable for us until it became its own thing.
-We hope you enjoy using Nullstack as much as we do because that's what keeps this project going forward.
-The sole purpose of Nullstack is to simplify the development by eliminating glue code and letting you focus on the logic of your application.
-It was created keeping in mind programmers used to developing entire systems alone, but it is easily scalable to small or even big teams, as long as each programmer knows the flow of the feature they are to develop.
-With the stack of technologies used in the web nowadays, the most common flow is something like this:
-Note that all you wanted was to show something from the database into a view. With Nullstack, that’s all you need to concern yourself with. Everything else is “glue code” and the framework should take care of it for you.
-If you’re used to working on more than one project at a time or even if you just happen to have to give sporadic maintenance to a lot of your old projects, you might have stumbled upon this scenario: you don’t remember exactly where in your code is the logic you’re trying to fix or improve.
-You might have a hook whose dependencies are local variables initialized with a redux state, which was stored at some point by an action declared somewhere in your source tree and called in who knows where.
-If everything pertaining to a single feature were to be in the same file, maybe you wouldn’t need to reverse engineer your own code every time you need to update or fix something.
-Putting everything in a single file may sound messy at a glance, but remember that you are the one who decides the granularity of this division.
-A "feature" might be an entire register form or something as small as a button that does some verifications before letting you submit that form. It’s entirely up to you, and since each component is as complete as an entire feature, you could call this button or even the entire form on other pages in your application. This leads us to True Componentization and Code Reusability.
-Components in Nullstack are self-sufficient.
-Most frameworks are specialized in a single layer, meaning that any component will be only as complete as its framework. When exporting a Nullstack component, all the code needed to run the feature is going to be together, without the need of allocating the other layers separately.
-As a side effect, entire applications can be used as components, and mounted in other applications as engines.
-At first glance, classes may look more verbose than the trendy functional components. -This section will explain the reasons that lead us to favor classes in the development of Nullstack.
-The reasons are actually connected to some core principles of Nullstack, being:
-We didn’t want to introduce a “Nullstack way” of doing things and wanted it to be accessible to anyone with some Javascript knowledge.
-That being said, the first big problem was to address state management in a vanilla Javascript way. Supporting functional components would require a solution similar to the hooks of React.js that would be considered a mannerism of the framework.
-Since we opted out of immutability as a framework constraint, we are allowed to use the native way of setting simple variables. This removes the complexity of state management that created the need of third-party state management libraries in the first place.
-Nullstack borrows the concept of “battery-included” from Ember.js, but allows you to change batteries. Everything you need to make an application should be part of the framework, and still be flexible.
-A framework should do the heavy lifting and a programmer should focus on his own application. -For this reason, all you have to do is to declare your classes and let Nullstack instantiate them for you. That way, we removed the most painful aspect of dealing with classes while maintaining all of the advantages of them.
-Object-oriented versus functional is not a new topic, and lately the former seems to be bullied out of most frameworks, leaving no place for developers that enjoy this pattern.
-Admittedly classes took too long to be standardized into Javascript and the delay might have caused some traumatic bad implementations along the way.
-While object-oriented programming might not be the best solution for every problem, Nullstack allows you to import functions freely and use them in the moments when they should be the weapon of choice.
-Nullstack context uses the dependency injection pattern, which means that everything you need can be requested from the framework at the signature level of the function.
-The context is a horizontally scoped object that is injected in all of your function calls. The non-hierarchical nature of this pattern allows you to easily move around your component's logic as your application grows, while still avoiding problems like props drilling or filling your view layer with store declarations.
-This has two major advantages:
-You see the dependencies of your code at a function level instead of having them all imported on top of the file.
The framework is able to give you the most precise information about the specific environment for that function call.
The generated application is enough to have a PWA without thinking about boilerplates, but you are completely free to override the default behavior of each moving piece.
-A borrowed concept from Ruby is developer happiness. Nullstack aims to ease the developer’s life by simplifying everything possible, but without hiding things from you.
-The first developers we wanted to make happy are ourselves. We made Nullstack because we had fun in the process. It started as a simple prototype on top of React.js and we got carried away, each time making it more enjoyable for us until it became its own thing.
-We hope you enjoy using Nullstack as much as we do because that's what keeps this project going forward.
-The sole purpose of Nullstack is to simplify the development by eliminating glue code and letting you focus on the logic of your application.
\nIt was created keeping in mind programmers used to developing entire systems alone, but it is easily scalable to small or even big teams, as long as each programmer knows the flow of the feature they are to develop.
\nWith the stack of technologies used in the web nowadays, the most common flow is something like this:
\nNote that all you wanted was to show something from the database into a view. With Nullstack, that’s all you need to concern yourself with. Everything else is “glue code” and the framework should take care of it for you.
\nIf you’re used to working on more than one project at a time or even if you just happen to have to give sporadic maintenance to a lot of your old projects, you might have stumbled upon this scenario: you don’t remember exactly where in your code is the logic you’re trying to fix or improve.
\nYou might have a hook whose dependencies are local variables initialized with a redux state, which was stored at some point by an action declared somewhere in your source tree and called in who knows where.
\nIf everything pertaining to a single feature were to be in the same file, maybe you wouldn’t need to reverse engineer your own code every time you need to update or fix something.
\nPutting everything in a single file may sound messy at a glance, but remember that you are the one who decides the granularity of this division.
\nA "feature" might be an entire register form or something as small as a button that does some verifications before letting you submit that form. It’s entirely up to you, and since each component is as complete as an entire feature, you could call this button or even the entire form on other pages in your application. This leads us to True Componentization and Code Reusability.
\nComponents in Nullstack are self-sufficient.
\nMost frameworks are specialized in a single layer, meaning that any component will be only as complete as its framework. When exporting a Nullstack component, all the code needed to run the feature is going to be together, without the need of allocating the other layers separately.
\nAs a side effect, entire applications can be used as components, and mounted in other applications as engines.
\nAt first glance, classes may look more verbose than the trendy functional components.\nThis section will explain the reasons that lead us to favor classes in the development of Nullstack.
\nThe reasons are actually connected to some core principles of Nullstack, being:
\nWe didn’t want to introduce a “Nullstack way” of doing things and wanted it to be accessible to anyone with some Javascript knowledge.
\nThat being said, the first big problem was to address state management in a vanilla Javascript way. Supporting functional components would require a solution similar to the hooks of React.js that would be considered a mannerism of the framework.
\nSince we opted out of immutability as a framework constraint, we are allowed to use the native way of setting simple variables. This removes the complexity of state management that created the need of third-party state management libraries in the first place.
\nNullstack borrows the concept of “battery-included” from Ember.js, but allows you to change batteries. Everything you need to make an application should be part of the framework, and still be flexible.
\nA framework should do the heavy lifting and a programmer should focus on his own application.\nFor this reason, all you have to do is to declare your classes and let Nullstack instantiate them for you. That way, we removed the most painful aspect of dealing with classes while maintaining all of the advantages of them.
\nObject-oriented versus functional is not a new topic, and lately the former seems to be bullied out of most frameworks, leaving no place for developers that enjoy this pattern.
\nAdmittedly classes took too long to be standardized into Javascript and the delay might have caused some traumatic bad implementations along the way.
\nWhile object-oriented programming might not be the best solution for every problem, Nullstack allows you to import functions freely and use them in the moments when they should be the weapon of choice.
\nNullstack context uses the dependency injection pattern, which means that everything you need can be requested from the framework at the signature level of the function.
\nThe context is a horizontally scoped object that is injected in all of your function calls. The non-hierarchical nature of this pattern allows you to easily move around your component's logic as your application grows, while still avoiding problems like props drilling or filling your view layer with store declarations.
\nThis has two major advantages:
\nYou see the dependencies of your code at a function level instead of having them all imported on top of the file.
The framework is able to give you the most precise information about the specific environment for that function call.
The generated application is enough to have a PWA without thinking about boilerplates, but you are completely free to override the default behavior of each moving piece.
\nA borrowed concept from Ruby is developer happiness. Nullstack aims to ease the developer’s life by simplifying everything possible, but without hiding things from you.
\nThe first developers we wanted to make happy are ourselves. We made Nullstack because we had fun in the process. It started as a simple prototype on top of React.js and we got carried away, each time making it more enjoyable for us until it became its own thing.
\nWe hope you enjoy using Nullstack as much as we do because that's what keeps this project going forward.
\n","description":"The sole purpose of Nullstack is to simplify the development by eliminating glue code and letting you focus on the logic of your application"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Why Nullstack Exists - Nullstack","description":"The sole purpose of Nullstack is to simplify the development by eliminating glue code and letting you focus on the logic of your application"}} \ No newline at end of file diff --git a/docs/application-startup.html b/docs/application-startup.html deleted file mode 100644 index fb40a902..00000000 --- a/docs/application-startup.html +++ /dev/null @@ -1,86 +0,0 @@ - - - - - -The index.js file at your application root is responsible for starting your application.
-When you run the application with npm start or node .production/server.js the index will call the start function in your src/Application.js.
The start function will run only once when your application is booted and is a good place for setting up your server context.
import Nullstack from 'nullstack';
-import database from './database';
-
-class Application extends Nullstack {
-
- static async start(context) {
- context.database = database;
- }
-
-}
-
-export default Application;
-
-A nice pattern to work with dependencies that require startup time configurations is to define a start function in the dependency and call it in the Application start function passing the server context.
import Nullstack from 'nullstack';
-import Dependency from './Dependency';
-
-class Application extends Nullstack {
-
- static async start(context) {
- Dependency.start(context);
- }
-
-}
-
-export default Application;
-
---🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
-
⚔ Learn about the context data.
The index.js file at your application root is responsible for starting your application.
-When you run the application with npm start or node .production/server.js the index will call the start function in your src/Application.js.
The start function will run only once when your application is booted and is a good place for setting up your server context.
import Nullstack from 'nullstack';
-import database from './database';
-
-class Application extends Nullstack {
-
- static async start(context) {
- context.database = database;
- }
-
-}
-
-export default Application;
-
-A nice pattern to work with dependencies that require startup time configurations is to define a start function in the dependency and call it in the Application start function passing the server context.
import Nullstack from 'nullstack';
-import Dependency from './Dependency';
-
-class Application extends Nullstack {
-
- static async start(context) {
- Dependency.start(context);
- }
-
-}
-
-export default Application;
-
---🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
-
⚔ Learn about the context data.
The index.js file at your application root is responsible for starting your application.
\nWhen you run the application with npm start or node .production/server.js the index will call the start function in your src/Application.js.
The start function will run only once when your application is booted and is a good place for setting up your server context.
import Nullstack from 'nullstack';\nimport database from './database';\n\nclass Application extends Nullstack {\n\n static async start(context) {\n context.database = database;\n }\n\n}\n\nexport default Application;\n\nA nice pattern to work with dependencies that require startup time configurations is to define a start function in the dependency and call it in the Application start function passing the server context.
import Nullstack from 'nullstack';\nimport Dependency from './Dependency';\n\nclass Application extends Nullstack {\n\n static async start(context) {\n Dependency.start(context);\n }\n\n}\n\nexport default Application;\n\n\n\n🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
\n
⚔ Learn about the context data.
A curated list of Nullstack components made by the community.
If you want to add a component to this list open an issue on github.
🤘 Nullstack é BR porr@!
A curated list of Nullstack components made by the community.
If you want to add a component to this list open an issue on github.
🤘 Nullstack é BR porr@!
objectIt gives you information about the element dataset.
-You can use this key to avoid polluting your DOM with invalid attributes.
---💡 This helps Nullstack set attributes without wasting time validating them.
-
Any data-* attributes will receive a respective camelized key on the data object.
You can assign data attributes both via data-* and a data key that accepts an object with camelized keys.
The kebab version is also available in the context.
-import Nullstack from 'nullstack';
-
-class ContextData extends Nullstack {
-
- count = 1;
-
- calculate({data}) {
- this.count = this.count * data.multiply + data.sum;
- }
-
- renderInner(context) {
- const {data} = context;
- return (
- <div data={data}>
- {data.frameworkName}
- is same as
- {context['data-framework-name']}
- </div>
- )
- }
-
- render({data}) {
- return (
- <div>
- <button onclick={this.calculate} data-multiply={3} data={{sum: 2}}>
- Calculate
- </button>
- <Inner data-framework-name="Nullstack" />
- </div>
- )
- }
-
-}
-
-export default ContextData;
-
---💡 Camelized keys from the
-dataobject will result in kebab attributes in the DOM.
⚔ Learn about the context environment.
objectIt gives you information about the element dataset.
-You can use this key to avoid polluting your DOM with invalid attributes.
---💡 This helps Nullstack set attributes without wasting time validating them.
-
Any data-* attributes will receive a respective camelized key on the data object.
You can assign data attributes both via data-* and a data key that accepts an object with camelized keys.
The kebab version is also available in the context.
-import Nullstack from 'nullstack';
-
-class ContextData extends Nullstack {
-
- count = 1;
-
- calculate({data}) {
- this.count = this.count * data.multiply + data.sum;
- }
-
- renderInner(context) {
- const {data} = context;
- return (
- <div data={data}>
- {data.frameworkName}
- is same as
- {context['data-framework-name']}
- </div>
- )
- }
-
- render({data}) {
- return (
- <div>
- <button onclick={this.calculate} data-multiply={3} data={{sum: 2}}>
- Calculate
- </button>
- <Inner data-framework-name="Nullstack" />
- </div>
- )
- }
-
-}
-
-export default ContextData;
-
---💡 Camelized keys from the
-dataobject will result in kebab attributes in the DOM.
⚔ Learn about the context environment.
objectIt gives you information about the element dataset.
\nYou can use this key to avoid polluting your DOM with invalid attributes.
\n\n\n💡 This helps Nullstack set attributes without wasting time validating them.
\n
Any data-* attributes will receive a respective camelized key on the data object.
You can assign data attributes both via data-* and a data key that accepts an object with camelized keys.
The kebab version is also available in the context.
\nimport Nullstack from 'nullstack';\n\nclass ContextData extends Nullstack {\n\n count = 1;\n\n calculate({data}) {\n this.count = this.count * data.multiply + data.sum;\n }\n\n renderInner(context) {\n const {data} = context;\n return (\n <div data={data}>\n {data.frameworkName}\n is same as\n {context['data-framework-name']}\n </div>\n )\n }\n \n render({data}) {\n return (\n <div> \n <button onclick={this.calculate} data-multiply={3} data={{sum: 2}}>\n Calculate\n </button>\n <Inner data-framework-name=\"Nullstack\" />\n </div>\n )\n }\n\n}\n\nexport default ContextData;\n\n\n\n💡 Camelized keys from the
\ndataobject will result in kebab attributes in the DOM.
⚔ Learn about the context environment.
objectIt gives you information about the current environment.
-The following keys are available in the object:
-booleanbooleanbooleanbooleanbooleanstringimport Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- render({environment}) {
- return (
- <div>
- {environment.client && <p>I'm in the client</p>}
- {environment.server && <p>I'm in the server</p>}
- {environment.development && <p>I'm in development mode</p>}
- {environment.production && <p>I'm in production mode</p>}
- {environment.static && <p>I'm in a static site</p>}
- <p> My key is {environment.key}</p>
- </div>
- )
- }
-
-}
-
-export default Page;
-
-The environment key is an md5 hash of the current environment folder outputs. The key is appended to assets and static API path to assist cache control.
-⚔ Learn about the context page.
objectIt gives you information about the current environment.
-The following keys are available in the object:
-booleanbooleanbooleanbooleanbooleanstringimport Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- render({environment}) {
- return (
- <div>
- {environment.client && <p>I'm in the client</p>}
- {environment.server && <p>I'm in the server</p>}
- {environment.development && <p>I'm in development mode</p>}
- {environment.production && <p>I'm in production mode</p>}
- {environment.static && <p>I'm in a static site</p>}
- <p> My key is {environment.key}</p>
- </div>
- )
- }
-
-}
-
-export default Page;
-
-The environment key is an md5 hash of the current environment folder outputs. The key is appended to assets and static API path to assist cache control.
-⚔ Learn about the context page.
objectIt gives you information about the current environment.
\nThe following keys are available in the object:
\nbooleanbooleanbooleanbooleanbooleanstringimport Nullstack from 'nullstack';\n\nclass Page extends Nullstack {\n \n render({environment}) {\n return (\n <div> \n {environment.client && <p>I'm in the client</p>}\n {environment.server && <p>I'm in the server</p>}\n {environment.development && <p>I'm in development mode</p>}\n {environment.production && <p>I'm in production mode</p>}\n {environment.static && <p>I'm in a static site</p>}\n <p> My key is {environment.key}</p>\n </div>\n )\n }\n\n}\n\nexport default Page;\n\nThe environment key is an md5 hash of the current environment folder outputs. The key is appended to assets and static API path to assist cache control.
\n⚔ Learn about the context page.
objectIt gives you information about the document head metatags.
page keys will be used to generate metatags during server-side rendering and must be assigned before initiate while this resolved.
The following keys are available in the object:
-stringstring (absolute or relative URL)stringstring (absolute or relative URL)stringstringobjectstringnumbernumberWhen the title key is assigned on the client-side, the document title will be updated.
Nullstack uses the changes and priority keys to generate the sitemap.xml.
The sitemap is generated automatically only when using static site generation and must be manually generated in server-side rendered applications.
-The changes key represents the changefreq key in the sitemap.xml and if assigned must be one of the following values:
The priority key is a number between 0.0 and 1.0 that represents the priority key in the sitemap.xml.
Nullstack does not set a default priority, however, sitemaps assume a 0.5 priority when not explicitly set.
Besides title and locale all other keys have sensible defaults generated based on the application scope.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- prepare({project, page}) {
- page.title = `${project.name} - Page Title`;
- page.image = '/image.jpg';
- page.description = 'Page meta description';
- page.canonical = 'http://absolute.url/canonical-link';
- page.locale = 'pt-BR';
- page.robots = 'index, follow';
- page.schema = {};
- page.changes = 'weekly';
- page.priority = 1;
- }
-
- render({page}) {
- return (
- <div>
- <h1>{page.title}</h1>
- <p>{page.description}</p>
- </div>
- )
- }
-
-}
-
-export default Page;
-
-Updating page.title will raise a custom event.
import Nullstack from 'nullstack';
-
-class Analytics extends Nullstack {
-
- hydrate({page}) {
- window.addEventListener(page.event, () => {
- console.log(`New title: ${page.title}`);
- });
- }
-
-}
-
-export default Analytics;
-
---🔥
-page.eventis only available in client functions/lifecycles.
If during the server-side render process the page.status has any value besides 200, your application will receive another render pass that gives you the chance to adjust the interface according to the status.
The status key will be raised with the HTTP response.
The page status will be modified to 500 and receive another render pass if the page raise an exception while rendering.
The status of server functions responses will be set to the page.status.
import Nullstack from 'nullstack';
-import ErrorPage from './ErrorPage';
-import HomePage from './HomePage';
-
-class Application extends Nullstack {
-
- // ...
-
- render({page}) {
- return (
- <main>
- {page.status !== 200 && <ErrorPage route="*" />}
- <HomePage route="/" />
- </main>
- )
- }
-
-}
-
-export default Application;
-
---🔥 Assigning to the
-statuskey during the single-page application mode will have no effect.
⚔ Learn about the context project.
objectIt gives you information about the document head metatags.
page keys will be used to generate metatags during server-side rendering and must be assigned before initiate while this resolved.
The following keys are available in the object:
-stringstring (absolute or relative URL)stringstring (absolute or relative URL)stringstringobjectstringnumbernumberWhen the title key is assigned on the client-side, the document title will be updated.
Nullstack uses the changes and priority keys to generate the sitemap.xml.
The sitemap is generated automatically only when using static site generation and must be manually generated in server-side rendered applications.
-The changes key represents the changefreq key in the sitemap.xml and if assigned must be one of the following values:
The priority key is a number between 0.0 and 1.0 that represents the priority key in the sitemap.xml.
Nullstack does not set a default priority, however, sitemaps assume a 0.5 priority when not explicitly set.
Besides title and locale all other keys have sensible defaults generated based on the application scope.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- prepare({project, page}) {
- page.title = `${project.name} - Page Title`;
- page.image = '/image.jpg';
- page.description = 'Page meta description';
- page.canonical = 'http://absolute.url/canonical-link';
- page.locale = 'pt-BR';
- page.robots = 'index, follow';
- page.schema = {};
- page.changes = 'weekly';
- page.priority = 1;
- }
-
- render({page}) {
- return (
- <div>
- <h1>{page.title}</h1>
- <p>{page.description}</p>
- </div>
- )
- }
-
-}
-
-export default Page;
-
-Updating page.title will raise a custom event.
import Nullstack from 'nullstack';
-
-class Analytics extends Nullstack {
-
- hydrate({page}) {
- window.addEventListener(page.event, () => {
- console.log(`New title: ${page.title}`);
- });
- }
-
-}
-
-export default Analytics;
-
---🔥
-page.eventis only available in client functions/lifecycles.
If during the server-side render process the page.status has any value besides 200, your application will receive another render pass that gives you the chance to adjust the interface according to the status.
The status key will be raised with the HTTP response.
The page status will be modified to 500 and receive another render pass if the page raise an exception while rendering.
The status of server functions responses will be set to the page.status.
import Nullstack from 'nullstack';
-import ErrorPage from './ErrorPage';
-import HomePage from './HomePage';
-
-class Application extends Nullstack {
-
- // ...
-
- render({page}) {
- return (
- <main>
- {page.status !== 200 && <ErrorPage route="*" />}
- <HomePage route="/" />
- </main>
- )
- }
-
-}
-
-export default Application;
-
---🔥 Assigning to the
-statuskey during the single-page application mode will have no effect.
⚔ Learn about the context project.
objectIt gives you information about the document head metatags.
page keys will be used to generate metatags during server-side rendering and must be assigned before initiate while this resolved.
The following keys are available in the object:
\nstringstring (absolute or relative URL)stringstring (absolute or relative URL)stringstringobjectstringnumbernumberWhen the title key is assigned on the client-side, the document title will be updated.
Nullstack uses the changes and priority keys to generate the sitemap.xml.
The sitemap is generated automatically only when using static site generation and must be manually generated in server-side rendered applications.
\nThe changes key represents the changefreq key in the sitemap.xml and if assigned must be one of the following values:
The priority key is a number between 0.0 and 1.0 that represents the priority key in the sitemap.xml.
Nullstack does not set a default priority, however, sitemaps assume a 0.5 priority when not explicitly set.
Besides title and locale all other keys have sensible defaults generated based on the application scope.
import Nullstack from 'nullstack';\n\nclass Page extends Nullstack {\n\n prepare({project, page}) {\n page.title = `${project.name} - Page Title`;\n page.image = '/image.jpg';\n page.description = 'Page meta description';\n page.canonical = 'http://absolute.url/canonical-link';\n page.locale = 'pt-BR';\n page.robots = 'index, follow';\n page.schema = {};\n page.changes = 'weekly';\n page.priority = 1;\n }\n\n render({page}) {\n return (\n <div>\n <h1>{page.title}</h1>\n <p>{page.description}</p>\n </div>\n )\n }\n\n}\n\nexport default Page;\n\nUpdating page.title will raise a custom event.
import Nullstack from 'nullstack';\n\nclass Analytics extends Nullstack {\n\n hydrate({page}) {\n window.addEventListener(page.event, () => {\n console.log(`New title: ${page.title}`);\n });\n }\n\n}\n\nexport default Analytics;\n\n\n\n🔥
\npage.eventis only available in client functions/lifecycles.
If during the server-side render process the page.status has any value besides 200, your application will receive another render pass that gives you the chance to adjust the interface according to the status.
The status key will be raised with the HTTP response.
The page status will be modified to 500 and receive another render pass if the page raise an exception while rendering.
The status of server functions responses will be set to the page.status.
import Nullstack from 'nullstack';\nimport ErrorPage from './ErrorPage';\nimport HomePage from './HomePage';\n\nclass Application extends Nullstack {\n\n // ...\n\n render({page}) {\n return (\n <main>\n {page.status !== 200 && <ErrorPage route=\"*\" />}\n <HomePage route=\"/\" />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\n\n\n🔥 Assigning to the
\nstatuskey during the single-page application mode will have no effect.
⚔ Learn about the context project.
objectIt gives you information about the app manifest and some metatags.
-project keys will be used to generate metatags during server-side rendering and must be assigned before initiate is resolved.
project keys will be used to generate the app manifest and should be set during the application startup.
The disallow key will be used to generate the robots.txt and should be set during the application startup.
project keys are frozen after the application startup.
The following keys are available in the object:
-stringstringstringstringstringstringstringstringstringstringobjectstring (relative or absolute url)string array (relative paths)boolean or string (relative or absolute url)string (absolute url)string (http or https)Besides domain, name and color all other keys have sensible defaults generated based on the application scope.
If you do not declare the icons key, Nullstack will scan any icons with the name following the pattern "icon-[WIDTH]x[HEIGHT].png" in your public folder.
If the sitemap key is set to true your robots.txt file will point the sitemap to https://${project.domain}/sitemap.xml.
The cdn key will prefix your asset bundles and will be available in the context so you can manually prefix other assets.
The protocol key is "http" in development mode and "https" in production mode by default.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({project}) {
- project.name = 'Nullstack';
- project.shortName = 'Nullstack';
- project.domain = 'nullstack.app';
- project.color = '#d22365';
- project.backgroundColor = '#d22365';
- project.type = 'website';
- project.display = 'standalone';
- project.orientation = 'portrait';
- project.scope = '/';
- project.root = '/';
- project.icons = {
- '72': '/icon-72x72.png',
- '128': '/icon-128x128.png',
- '512': '/icon-512x512.png'
- };
- project.favicon = '/favicon.png';
- project.disallow = ['/admin'];
- project.sitemap = true;
- project.cdn = 'cdn.nullstack.app';
- project.protocol = 'https';
- }
-
- prepare({project, page}) {
- page.title = project.name;
- }
-
-}
-
-export default Application;
-
---💡 You can override the automatically generated manifest.json and robots.txt by serving your own file from the public folder
-
⚔ Learn about the context settings.
objectIt gives you information about the app manifest and some metatags.
-project keys will be used to generate metatags during server-side rendering and must be assigned before initiate is resolved.
project keys will be used to generate the app manifest and should be set during the application startup.
The disallow key will be used to generate the robots.txt and should be set during the application startup.
project keys are frozen after the application startup.
The following keys are available in the object:
-stringstringstringstringstringstringstringstringstringstringobjectstring (relative or absolute url)string array (relative paths)boolean or string (relative or absolute url)string (absolute url)string (http or https)Besides domain, name and color all other keys have sensible defaults generated based on the application scope.
If you do not declare the icons key, Nullstack will scan any icons with the name following the pattern "icon-[WIDTH]x[HEIGHT].png" in your public folder.
If the sitemap key is set to true your robots.txt file will point the sitemap to https://${project.domain}/sitemap.xml.
The cdn key will prefix your asset bundles and will be available in the context so you can manually prefix other assets.
The protocol key is "http" in development mode and "https" in production mode by default.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({project}) {
- project.name = 'Nullstack';
- project.shortName = 'Nullstack';
- project.domain = 'nullstack.app';
- project.color = '#d22365';
- project.backgroundColor = '#d22365';
- project.type = 'website';
- project.display = 'standalone';
- project.orientation = 'portrait';
- project.scope = '/';
- project.root = '/';
- project.icons = {
- '72': '/icon-72x72.png',
- '128': '/icon-128x128.png',
- '512': '/icon-512x512.png'
- };
- project.favicon = '/favicon.png';
- project.disallow = ['/admin'];
- project.sitemap = true;
- project.cdn = 'cdn.nullstack.app';
- project.protocol = 'https';
- }
-
- prepare({project, page}) {
- page.title = project.name;
- }
-
-}
-
-export default Application;
-
---💡 You can override the automatically generated manifest.json and robots.txt by serving your own file from the public folder
-
⚔ Learn about the context settings.
objectIt gives you information about the app manifest and some metatags.
\nproject keys will be used to generate metatags during server-side rendering and must be assigned before initiate is resolved.
project keys will be used to generate the app manifest and should be set during the application startup.
The disallow key will be used to generate the robots.txt and should be set during the application startup.
project keys are frozen after the application startup.
The following keys are available in the object:
\nstringstringstringstringstringstringstringstringstringstringobjectstring (relative or absolute url)string array (relative paths)boolean or string (relative or absolute url)string (absolute url)string (http or https)Besides domain, name and color all other keys have sensible defaults generated based on the application scope.
If you do not declare the icons key, Nullstack will scan any icons with the name following the pattern "icon-[WIDTH]x[HEIGHT].png" in your public folder.
If the sitemap key is set to true your robots.txt file will point the sitemap to https://${project.domain}/sitemap.xml.
The cdn key will prefix your asset bundles and will be available in the context so you can manually prefix other assets.
The protocol key is "http" in development mode and "https" in production mode by default.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({project}) {\n project.name = 'Nullstack';\n project.shortName = 'Nullstack';\n project.domain = 'nullstack.app';\n project.color = '#d22365';\n project.backgroundColor = '#d22365';\n project.type = 'website';\n project.display = 'standalone';\n project.orientation = 'portrait';\n project.scope = '/';\n project.root = '/';\n project.icons = {\n '72': '/icon-72x72.png',\n '128': '/icon-128x128.png',\n '512': '/icon-512x512.png'\n };\n project.favicon = '/favicon.png';\n project.disallow = ['/admin'];\n project.sitemap = true;\n project.cdn = 'cdn.nullstack.app';\n project.protocol = 'https';\n }\n\n prepare({project, page}) {\n page.title = project.name;\n }\n\n}\n\nexport default Application;\n\n\n\n💡 You can override the automatically generated manifest.json and robots.txt by serving your own file from the public folder
\n
⚔ Learn about the context settings.
objectYou can use it to configure your application with private information.
-secrets keys are frozen after the application startup.
The following keys are available in the object:
-objectobjectanyYou can assign keys to development or production keys in order to have different secrets per environment.
If you assign a key directly to the secrets object it will be available in both environments.
When reading from a key you must read directly from the secrets object and Nullstack will return the best-suited value for that environment.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({secrets}) {
- secrets.development.privateKey = 'SANDBOX_API_KEY';
- secrets.production.privateKey = 'PRODUCTION_API_KEY';
- secrets.endpoint = 'https://domain.com/api';
- }
-
- static async fetchFromApi({secrets}) {
- const response = await fetch(secrets.endpoint, {
- headers: {
- Authorization: `Bearer ${secrets.privateKey}`
- }
- });
- return await response.json();
- }
-
-}
-
-export default Application;
-
-Any environment key starting with NULLSTACK_SECRETS_ will be mapped to the secrets in that environment.
---🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY will be mapped to
-secrets.privateKey
⚔ Learn about the instance self.
-objectYou can use it to configure your application with private information.
-secrets keys are frozen after the application startup.
The following keys are available in the object:
-objectobjectanyYou can assign keys to development or production keys in order to have different secrets per environment.
If you assign a key directly to the secrets object it will be available in both environments.
When reading from a key you must read directly from the secrets object and Nullstack will return the best-suited value for that environment.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({secrets}) {
- secrets.development.privateKey = 'SANDBOX_API_KEY';
- secrets.production.privateKey = 'PRODUCTION_API_KEY';
- secrets.endpoint = 'https://domain.com/api';
- }
-
- static async fetchFromApi({secrets}) {
- const response = await fetch(secrets.endpoint, {
- headers: {
- Authorization: `Bearer ${secrets.privateKey}`
- }
- });
- return await response.json();
- }
-
-}
-
-export default Application;
-
-Any environment key starting with NULLSTACK_SECRETS_ will be mapped to the secrets in that environment.
---🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY will be mapped to
-secrets.privateKey
⚔ Learn about the instance self.
-objectYou can use it to configure your application with private information.
\nsecrets keys are frozen after the application startup.
The following keys are available in the object:
\nobjectobjectanyYou can assign keys to development or production keys in order to have different secrets per environment.
If you assign a key directly to the secrets object it will be available in both environments.
When reading from a key you must read directly from the secrets object and Nullstack will return the best-suited value for that environment.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({secrets}) {\n secrets.development.privateKey = 'SANDBOX_API_KEY';\n secrets.production.privateKey = 'PRODUCTION_API_KEY';\n secrets.endpoint = 'https://domain.com/api';\n }\n\n static async fetchFromApi({secrets}) {\n const response = await fetch(secrets.endpoint, {\n headers: {\n Authorization: `Bearer ${secrets.privateKey}`\n }\n });\n return await response.json();\n }\n\n}\n\nexport default Application;\n\nAny environment key starting with NULLSTACK_SECRETS_ will be mapped to the secrets in that environment.
\n\n\n🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY will be mapped to
\nsecrets.privateKey
⚔ Learn about the instance self.
\n","description":"The secrets object is a proxy in the Nullstack Context available in server which you can use to configure your application with private information"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Context Secrets - Nullstack","description":"The secrets object is a proxy in the Nullstack Context available in server which you can use to configure your application with private information"}} \ No newline at end of file diff --git a/docs/context-settings.html b/docs/context-settings.html deleted file mode 100644 index a8e718b3..00000000 --- a/docs/context-settings.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - -objectYou can use it to configure your application with public information.
-settings keys are frozen after the application startup.
The following keys are available in the object:
-objectobjectanyYou can assign keys to development or production keys in order to have different settings per environment.
If you assign a key directly to the settings object it will be available in both environments.
When reading from a key you must read directly from the settings object and Nullstack will return the best-suited value for that environment.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({settings}) {
- settings.development.publicKey = 'SANDBOX_API_KEY';
- settings.production.publicKey = 'PRODUCTION_API_KEY';
- settings.endpoint = 'https://domain.com/api';
- }
-
- async hydrate({settings}) {
- const response = await fetch(settings.endpoint, {
- headers: {
- Authorization: `Bearer ${settings.publicKey}`
- }
- });
- this.data = await response.json();
- }
-
-}
-
-export default Application;
-
-Any environment key starting with NULLSTACK_SETTINGS_ will be mapped to the settings in that environment.
---🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY will be mapped to
-settings.publicKey
⚔ Learn about the context secrets.
objectYou can use it to configure your application with public information.
-settings keys are frozen after the application startup.
The following keys are available in the object:
-objectobjectanyYou can assign keys to development or production keys in order to have different settings per environment.
If you assign a key directly to the settings object it will be available in both environments.
When reading from a key you must read directly from the settings object and Nullstack will return the best-suited value for that environment.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({settings}) {
- settings.development.publicKey = 'SANDBOX_API_KEY';
- settings.production.publicKey = 'PRODUCTION_API_KEY';
- settings.endpoint = 'https://domain.com/api';
- }
-
- async hydrate({settings}) {
- const response = await fetch(settings.endpoint, {
- headers: {
- Authorization: `Bearer ${settings.publicKey}`
- }
- });
- this.data = await response.json();
- }
-
-}
-
-export default Application;
-
-Any environment key starting with NULLSTACK_SETTINGS_ will be mapped to the settings in that environment.
---🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY will be mapped to
-settings.publicKey
⚔ Learn about the context secrets.
objectYou can use it to configure your application with public information.
\nsettings keys are frozen after the application startup.
The following keys are available in the object:
\nobjectobjectanyYou can assign keys to development or production keys in order to have different settings per environment.
If you assign a key directly to the settings object it will be available in both environments.
When reading from a key you must read directly from the settings object and Nullstack will return the best-suited value for that environment.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({settings}) {\n settings.development.publicKey = 'SANDBOX_API_KEY';\n settings.production.publicKey = 'PRODUCTION_API_KEY';\n settings.endpoint = 'https://domain.com/api';\n }\n\n async hydrate({settings}) {\n const response = await fetch(settings.endpoint, {\n headers: {\n Authorization: `Bearer ${settings.publicKey}`\n }\n });\n this.data = await response.json();\n }\n\n}\n\nexport default Application;\n\nAny environment key starting with NULLSTACK_SETTINGS_ will be mapped to the settings in that environment.
\n\n\n🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY will be mapped to
\nsettings.publicKey
⚔ Learn about the context secrets.
Every function in Nullstack receives a context as the argument.
-There are two contexts, one for the client and another one for the server.
-The client context lives as long as the browser tab is open.
-The server context lives as long as the server is running.
-Both contexts are proxies that merge the keys of 3 objects:
-These are the information that the framework makes available to you by default.
-When you set a key to the context it will be available for destructuring at any depth of the application, even the parents of your component or 3rd party applications that mount your component.
-Updating a key in the context causes the application to re-render automatically.
-You can think of this as a single concept to replace stores, contexts, services, and reducers at the same time using the dependency injection pattern with vanilla javascript objects instead.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- prepare(context) {
- context.count = 1;
- }
-
- static async updateTotalCount(context) {
- context.totalCount += context.count;
- }
-
- async double(context) {
- context.count += context.count;
- await this.updateTotalCount();
- }
-
- render({count}) {
- return (
- <button onclick={this.double}> {count} </button>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- static async start(context) {
- context.totalCount = 0;
- }
-
- render({count}) {
- return (
- <main>
- {(!count || count < 10) && <Counter />}
- </main>
- )
- }
-
-}
-
-export default Application;
-
-This one contains the attributes you declare in your tag, including data.
If the attribute is declared in a component tag every function of that component will have access to that attribute in its context.
-If the attribute is declared in a tag that has an event it will be merged into the event function context.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- add(context) {
- context.count += context.delta + context.amount;
- }
-
- render({count, delta}) {
- return (
- <button onclick={this.add} amount={1}>
- add {delta} to {count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- prepare(context) {
- context.count = 0;
- }
-
- render() {
- return (
- <main>
- <Counter delta={2} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Every function of subclasses of Nullstack is injected with a copy of the instance context merged with its arguments.
-Arguments are optional, but if declared, must be a single object with keys of your choice.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- add(context) {
- context.count += context.amount || 1;
- }
-
- prepare(context) {
- context.count = 0;
- this.add(); // sums 1
- this.add({amount: 2}); // sums 2
- }
-
- async initiate(context) {
- console.log(context.count); // 3
- }
-
-}
-
-export default Counter;
-
-⚔ Learn about routes and params.
-Every function in Nullstack receives a context as the argument.
-There are two contexts, one for the client and another one for the server.
-The client context lives as long as the browser tab is open.
-The server context lives as long as the server is running.
-Both contexts are proxies that merge the keys of 3 objects:
-These are the information that the framework makes available to you by default.
-When you set a key to the context it will be available for destructuring at any depth of the application, even the parents of your component or 3rd party applications that mount your component.
-Updating a key in the context causes the application to re-render automatically.
-You can think of this as a single concept to replace stores, contexts, services, and reducers at the same time using the dependency injection pattern with vanilla javascript objects instead.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- prepare(context) {
- context.count = 1;
- }
-
- static async updateTotalCount(context) {
- context.totalCount += context.count;
- }
-
- async double(context) {
- context.count += context.count;
- await this.updateTotalCount();
- }
-
- render({count}) {
- return (
- <button onclick={this.double}> {count} </button>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- static async start(context) {
- context.totalCount = 0;
- }
-
- render({count}) {
- return (
- <main>
- {(!count || count < 10) && <Counter />}
- </main>
- )
- }
-
-}
-
-export default Application;
-
-This one contains the attributes you declare in your tag, including data.
If the attribute is declared in a component tag every function of that component will have access to that attribute in its context.
-If the attribute is declared in a tag that has an event it will be merged into the event function context.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- add(context) {
- context.count += context.delta + context.amount;
- }
-
- render({count, delta}) {
- return (
- <button onclick={this.add} amount={1}>
- add {delta} to {count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- prepare(context) {
- context.count = 0;
- }
-
- render() {
- return (
- <main>
- <Counter delta={2} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Every function of subclasses of Nullstack is injected with a copy of the instance context merged with its arguments.
-Arguments are optional, but if declared, must be a single object with keys of your choice.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- add(context) {
- context.count += context.amount || 1;
- }
-
- prepare(context) {
- context.count = 0;
- this.add(); // sums 1
- this.add({amount: 2}); // sums 2
- }
-
- async initiate(context) {
- console.log(context.count); // 3
- }
-
-}
-
-export default Counter;
-
-⚔ Learn about routes and params.
-Every function in Nullstack receives a context as the argument.
\nThere are two contexts, one for the client and another one for the server.
\nThe client context lives as long as the browser tab is open.
\nThe server context lives as long as the server is running.
\nBoth contexts are proxies that merge the keys of 3 objects:
\nThese are the information that the framework makes available to you by default.
\nWhen you set a key to the context it will be available for destructuring at any depth of the application, even the parents of your component or 3rd party applications that mount your component.
\nUpdating a key in the context causes the application to re-render automatically.
\nYou can think of this as a single concept to replace stores, contexts, services, and reducers at the same time using the dependency injection pattern with vanilla javascript objects instead.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n prepare(context) {\n context.count = 1;\n }\n\n static async updateTotalCount(context) {\n context.totalCount += context.count;\n }\n\n async double(context) {\n context.count += context.count;\n await this.updateTotalCount();\n }\n\n render({count}) {\n return (\n <button onclick={this.double}> {count} </button>\n )\n }\n\n}\n\nexport default Counter;\n\nimport Nullstack from 'nullstack';\nimport Counter from './Counter';\n\nclass Application extends Nullstack {\n\n static async start(context) {\n context.totalCount = 0;\n }\n\n render({count}) {\n return (\n <main>\n {(!count || count < 10) && <Counter />}\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nThis one contains the attributes you declare in your tag, including data.
If the attribute is declared in a component tag every function of that component will have access to that attribute in its context.
\nIf the attribute is declared in a tag that has an event it will be merged into the event function context.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n add(context) {\n context.count += context.delta + context.amount;\n }\n\n render({count, delta}) {\n return (\n <button onclick={this.add} amount={1}>\n add {delta} to {count}\n </button>\n )\n }\n\n}\n\nexport default Counter;\n\nimport Nullstack from 'nullstack';\nimport Counter from './Counter';\n\nclass Application extends Nullstack {\n\n prepare(context) {\n context.count = 0;\n }\n\n render() {\n return (\n <main>\n <Counter delta={2} />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nEvery function of subclasses of Nullstack is injected with a copy of the instance context merged with its arguments.
\nArguments are optional, but if declared, must be a single object with keys of your choice.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n add(context) {\n context.count += context.amount || 1;\n }\n\n prepare(context) {\n context.count = 0;\n this.add(); // sums 1\n this.add({amount: 2}); // sums 2\n }\n\n async initiate(context) {\n console.log(context.count); // 3\n }\n\n}\n\nexport default Counter;\n\n⚔ Learn about routes and params.
\n","description":"Every function in Nullstack receives a context as the argument."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Context - Nullstack","description":"Every function in Nullstack receives a context as the argument."}} \ No newline at end of file diff --git a/docs/contexto-page.html b/docs/contexto-page.html deleted file mode 100644 index 3f813663..00000000 --- a/docs/contexto-page.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Perhaps you want to learn about how to make a 404 page with Nullstack?
-If you are looking for something else, you should read the documentation.
-Perhaps you want to learn about how to make a 404 page with Nullstack?
-If you are looking for something else, you should read the documentation.
-Perhaps you want to learn about how to make a 404 page with Nullstack?
\nIf you are looking for something else, you should read the documentation.
\n","description":"Sorry, this is not the page you are looking for.","status":404},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":404,"title":"Page Not Found - Nullstack","description":"Sorry, this is not the page you are looking for."}} \ No newline at end of file diff --git a/docs/contributors.html b/docs/contributors.html deleted file mode 100644 index ff359e84..00000000 --- a/docs/contributors.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - -Nullstack is being developed since January 2019 with features being extracted from freelancing projects.
At this point the API is stable, lifecycle methods and context keys will pretty much be frozen.
We are not yet on 1.0 but really close, the only thing missing is to test it on applications made outside the core team to figure out if it fits the needs of other programmers.
The next updates will be guided towards fixing any bugs that are found and focus on quality of life.
The updates listed on Nullstack issues are the next planned steps without any particular order.
Nullstack was developed by full-stack neuro-atypical freelancers.
With a heavy background in Rails, Ember.js, React.js and the Vue.js philosophy the inspirations took from those projects might be obvious.

Creator of the concept. Comes with new API proposals to its favorite rubber ducks and returns with commits.
Reverse engineered wishful thinking code into existence and then refactored it into a framework.

Rubber duck with human skills that makes sure the code is not going too far outside the box, then makes the box look nice.
API reviewer that developed third party projects to test proof of concepts from a front-end focused perspective.

Rubber duck with a neck to find inconsistencies and problems, waiting till an API is approved to force us into rewriting everything.
An early adopter of the framework that developed real production applications to validate how the parts fit together.

Freelance illustrator for 10 years. Warcraft addict, aspiring cosplayer and druid tanker in WoW.
Mother of Nulla-Chan and reads scripts here and there under pure pressure from Mortaro.

Experimentalist, universes writer, dreamer and developer when finds and plays the right untitled cassette tape.
User of undocumented features and creator of issues requiring documentation that he will do himself.

TipsCode instructor. Full-stack JavaScript developer, passionate about technology and servant of the Lord Jesus Christ.
In charge of creating content about Nullstack, classes, tips and tutorials. Focused in making Nullstack easy to use.
* The list might take a while to update due to GitHub API cache
* The list might take a while to update due to GitHub API cache
It's simple. Found a bug or want a new feature?
Create an issue or submit a pull request with tests.
Nullstack is being developed since January 2019 with features being extracted from freelancing projects.
At this point the API is stable, lifecycle methods and context keys will pretty much be frozen.
We are not yet on 1.0 but really close, the only thing missing is to test it on applications made outside the core team to figure out if it fits the needs of other programmers.
The next updates will be guided towards fixing any bugs that are found and focus on quality of life.
The updates listed on Nullstack issues are the next planned steps without any particular order.
Nullstack was developed by full-stack neuro-atypical freelancers.
With a heavy background in Rails, Ember.js, React.js and the Vue.js philosophy the inspirations took from those projects might be obvious.

Creator of the concept. Comes with new API proposals to its favorite rubber ducks and returns with commits.
Reverse engineered wishful thinking code into existence and then refactored it into a framework.

Rubber duck with human skills that makes sure the code is not going too far outside the box, then makes the box look nice.
API reviewer that developed third party projects to test proof of concepts from a front-end focused perspective.

Rubber duck with a neck to find inconsistencies and problems, waiting till an API is approved to force us into rewriting everything.
An early adopter of the framework that developed real production applications to validate how the parts fit together.

Freelance illustrator for 10 years. Warcraft addict, aspiring cosplayer and druid tanker in WoW.
Mother of Nulla-Chan and reads scripts here and there under pure pressure from Mortaro.

Experimentalist, universes writer, dreamer and developer when finds and plays the right untitled cassette tape.
User of undocumented features and creator of issues requiring documentation that he will do himself.

TipsCode instructor. Full-stack JavaScript developer, passionate about technology and servant of the Lord Jesus Christ.
In charge of creating content about Nullstack, classes, tips and tutorials. Focused in making Nullstack easy to use.
* The list might take a while to update due to GitHub API cache
* The list might take a while to update due to GitHub API cache
It's simple. Found a bug or want a new feature?
Create an issue or submit a pull request with tests.
Follow these steps and become a full-stack javascript developer!
Start your journey in Nullstack with these basic concepts
These are concepts that you will most likely learn as you need in your projects
The best way to learn Nullstack is by reading some code
Follow these steps and become a full-stack javascript developer!
Start your journey in Nullstack with these basic concepts
These are concepts that you will most likely learn as you need in your projects
The best way to learn Nullstack is by reading some code
Lifecycle methods are special named functions that you can declare in the class.
-Each lifecycle method runs in a specific order in a queue so it's guaranteed that all components initiated in that cycle will be prepared before the first one is initiated.
-This method is blocking and runs before the first time the component is rendered.
-You can use this function to set the state that the user will see before things are loaded.
-If the user is entering from this route prepare will run in the server before Nullstack server-side renders your application.
If the user is navigating from another route this method will run in the client.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- prepare() {
- this.date = new Date();
- }
-
- // ...
-
-}
-
-export default Component;
-
-This method can be async and runs right after the component is prepared and rendered for the first time.
-You can use this function to invoke another server function and load the data to present the page.
-If the user is entering from this route initiate will run in the server.
Nullstack will wait till the promise is resolved and then finally generate the HTML that will be served.
-If the user is navigating from another route this method will run in the client.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async initiate() {
- this.task = await getTaskByDay({
- day: this.date
- });
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Learn more about server functions.
-
This method is async and will only run in the client.
-This method will always run no matter which environment started the component.
-This is a good place to trigger dependencies that manipulate the dom or can only run on the client-side.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async hydrate() {
- this.timer = setInterval(() => {
- console.log(this.date);
- }, 1000);
- }
-
- // ...
-
-}
-
-export default Component;
-
-This method is async and will only run in the client.
-This method runs on every component anytime the application state changes.
---🔥 Be careful not to cause infinite loopings when mutating state inside
-update.
This will run right before rendering but will not block the rendering queue.
-The update function will not start running until the application is rendered after the initiate.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async update() {
- const today = new Date();
- if(today.getDay() != this.date.getDay()) {
- this.date = today;
- await this.initiate();
- }
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Lifecycle methods have no special side effects, you can call them manually without causing problems.
-
This method is async and will only run in the client.
-This method will run after your component leaves the DOM.
-This is the place to clean up whatever you set up in the hydrate method.
The instance will be garbage collected after the Promise is resolved.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async terminate() {
- clearInterval(this.timer);
- }
-
- // ...
-
-}
-
-export default Component;
-
-⚔ Learn about server functions.
-Lifecycle methods are special named functions that you can declare in the class.
-Each lifecycle method runs in a specific order in a queue so it's guaranteed that all components initiated in that cycle will be prepared before the first one is initiated.
-This method is blocking and runs before the first time the component is rendered.
-You can use this function to set the state that the user will see before things are loaded.
-If the user is entering from this route prepare will run in the server before Nullstack server-side renders your application.
If the user is navigating from another route this method will run in the client.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- prepare() {
- this.date = new Date();
- }
-
- // ...
-
-}
-
-export default Component;
-
-This method can be async and runs right after the component is prepared and rendered for the first time.
-You can use this function to invoke another server function and load the data to present the page.
-If the user is entering from this route initiate will run in the server.
Nullstack will wait till the promise is resolved and then finally generate the HTML that will be served.
-If the user is navigating from another route this method will run in the client.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async initiate() {
- this.task = await getTaskByDay({
- day: this.date
- });
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Learn more about server functions.
-
This method is async and will only run in the client.
-This method will always run no matter which environment started the component.
-This is a good place to trigger dependencies that manipulate the dom or can only run on the client-side.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async hydrate() {
- this.timer = setInterval(() => {
- console.log(this.date);
- }, 1000);
- }
-
- // ...
-
-}
-
-export default Component;
-
-This method is async and will only run in the client.
-This method runs on every component anytime the application state changes.
---🔥 Be careful not to cause infinite loopings when mutating state inside
-update.
This will run right before rendering but will not block the rendering queue.
-The update function will not start running until the application is rendered after the initiate.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async update() {
- const today = new Date();
- if(today.getDay() != this.date.getDay()) {
- this.date = today;
- await this.initiate();
- }
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Lifecycle methods have no special side effects, you can call them manually without causing problems.
-
This method is async and will only run in the client.
-This method will run after your component leaves the DOM.
-This is the place to clean up whatever you set up in the hydrate method.
The instance will be garbage collected after the Promise is resolved.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async terminate() {
- clearInterval(this.timer);
- }
-
- // ...
-
-}
-
-export default Component;
-
-⚔ Learn about server functions.
-Lifecycle methods are special named functions that you can declare in the class.
\nEach lifecycle method runs in a specific order in a queue so it's guaranteed that all components initiated in that cycle will be prepared before the first one is initiated.
\nThis method is blocking and runs before the first time the component is rendered.
\nYou can use this function to set the state that the user will see before things are loaded.
\nIf the user is entering from this route prepare will run in the server before Nullstack server-side renders your application.
If the user is navigating from another route this method will run in the client.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n prepare() {\n this.date = new Date();\n }\n\n // ...\n\n}\n\nexport default Component;\n\nThis method can be async and runs right after the component is prepared and rendered for the first time.
\nYou can use this function to invoke another server function and load the data to present the page.
\nIf the user is entering from this route initiate will run in the server.
Nullstack will wait till the promise is resolved and then finally generate the HTML that will be served.
\nIf the user is navigating from another route this method will run in the client.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async initiate() {\n this.task = await getTaskByDay({\n day: this.date\n });\n }\n\n // ...\n\n}\n\nexport default Component;\n\n\n\n✨ Learn more about server functions.
\n
This method is async and will only run in the client.
\nThis method will always run no matter which environment started the component.
\nThis is a good place to trigger dependencies that manipulate the dom or can only run on the client-side.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async hydrate() {\n this.timer = setInterval(() => {\n console.log(this.date);\n }, 1000);\n }\n\n // ...\n\n}\n\nexport default Component;\n\nThis method is async and will only run in the client.
\nThis method runs on every component anytime the application state changes.
\n\n\n🔥 Be careful not to cause infinite loopings when mutating state inside
\nupdate.
This will run right before rendering but will not block the rendering queue.
\nThe update function will not start running until the application is rendered after the initiate.
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async update() {\n const today = new Date();\n if(today.getDay() != this.date.getDay()) {\n this.date = today;\n await this.initiate();\n }\n }\n\n // ...\n\n}\n\nexport default Component;\n\n\n\n✨ Lifecycle methods have no special side effects, you can call them manually without causing problems.
\n
This method is async and will only run in the client.
\nThis method will run after your component leaves the DOM.
\nThis is the place to clean up whatever you set up in the hydrate method.
The instance will be garbage collected after the Promise is resolved.
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async terminate() {\n clearInterval(this.timer);\n }\n\n // ...\n\n}\n\nexport default Component;\n\n⚔ Learn about server functions.
\n","description":"Lifecycle methods are special named functions that you can declare in the class."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Full-Stack Lifecycle - Nullstack","description":"Lifecycle methods are special named functions that you can declare in the class."}} \ No newline at end of file diff --git a/docs/getting-started.html b/docs/getting-started.html deleted file mode 100644 index cc9e6d3f..00000000 --- a/docs/getting-started.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - ---📌 You can watch a video tutorial on our Youtube Channel.
-
Create full-stack javascript applications within seconds using npx to generate your project files from the latest template.
--🔥 The minimum required node.js version for development mode is 12.12.0.
-
--⚠ If the directory you are in contains spaces, you use Windows and
-npxgives errors, read about the known npx bug.
Replace project-name with your project name and run the command below to start a project:
npx create-nullstack-app project-name
-
-Change directory to the generated folder:
-cd project-name
-
-Install the dependencies:
-npm install
-
-Start the application in development mode:
-npm start
-
-The following folders and files will be generated:
-This is the Webpack entry point.
-Usually, you don't have to touch this file, but it is a convenient place to import global dependencies like CSS frameworks.
-This folder will contain the actual source code of your application.
-This is your application main file.
---✨ Learn more about the njs file extension.
-
The start function will be automatically called once when you run npm start, use it to populate your server context with things like database, settings, and secrets.
--✨ Learn more about the application startup.
-
This is an empty file just to demonstrate that you can use SCSS with Nullstack.
-It is a good practice to import a style file in a component with the same name.
---✨ Learn more about styles.
-
Every file in here will be available to anyone from the domain root.
-By default create-nullstack-app generates the icons required for your manifest.json and images for OG meta tags.
--✨ Learn more about manifest.json.
-
Be sure to replace these images with your project identity.
-This is the compiled result of your application in development mode.
---🔥 Do not touch this folder
-
This is the compiled result of your application in production mode.
---🔥 Do not touch this folder
-
--✨ Learn more about how to deploy a Nullstack application.
-
Warned on npx issues like #100, #110 and #143, it has an error when trying to resolve the path to his cache folder when contains spaces.
If this happens to you, our recommendations are:
-Using downloaded as you normally would with npm:
npm i -g create-nullstack-app
-create-nullstack-app project-name
-or, change the cache folder directory, as stated here and here:
-FirstName with the one used on your path and run:npm config set cache "C:\Users\FirstName~1\AppData\Roaming\npm-cache" --global
-
-npm config set cache C:\tmp\nodejs\npm-cache --global
-⚔ Create your first renderable component.
---📌 You can watch a video tutorial on our Youtube Channel.
-
Create full-stack javascript applications within seconds using npx to generate your project files from the latest template.
--🔥 The minimum required node.js version for development mode is 12.12.0.
-
--⚠ If the directory you are in contains spaces, you use Windows and
-npxgives errors, read about the known npx bug.
Replace project-name with your project name and run the command below to start a project:
npx create-nullstack-app project-name
-
-Change directory to the generated folder:
-cd project-name
-
-Install the dependencies:
-npm install
-
-Start the application in development mode:
-npm start
-
-The following folders and files will be generated:
-This is the Webpack entry point.
-Usually, you don't have to touch this file, but it is a convenient place to import global dependencies like CSS frameworks.
-This folder will contain the actual source code of your application.
-This is your application main file.
---✨ Learn more about the njs file extension.
-
The start function will be automatically called once when you run npm start, use it to populate your server context with things like database, settings, and secrets.
--✨ Learn more about the application startup.
-
This is an empty file just to demonstrate that you can use SCSS with Nullstack.
-It is a good practice to import a style file in a component with the same name.
---✨ Learn more about styles.
-
Every file in here will be available to anyone from the domain root.
-By default create-nullstack-app generates the icons required for your manifest.json and images for OG meta tags.
--✨ Learn more about manifest.json.
-
Be sure to replace these images with your project identity.
-This is the compiled result of your application in development mode.
---🔥 Do not touch this folder
-
This is the compiled result of your application in production mode.
---🔥 Do not touch this folder
-
--✨ Learn more about how to deploy a Nullstack application.
-
Warned on npx issues like #100, #110 and #143, it has an error when trying to resolve the path to his cache folder when contains spaces.
If this happens to you, our recommendations are:
-Using downloaded as you normally would with npm:
npm i -g create-nullstack-app
-create-nullstack-app project-name
-or, change the cache folder directory, as stated here and here:
-FirstName with the one used on your path and run:npm config set cache "C:\Users\FirstName~1\AppData\Roaming\npm-cache" --global
-
-npm config set cache C:\tmp\nodejs\npm-cache --global
-⚔ Create your first renderable component.
-\n\n📌 You can watch a video tutorial on our Youtube Channel.
\n
Create full-stack javascript applications within seconds using npx to generate your project files from the latest template.
\n\n🔥 The minimum required node.js version for development mode is 12.12.0.
\n
\n\n⚠ If the directory you are in contains spaces, you use Windows and
\nnpxgives errors, read about the known npx bug.
Replace project-name with your project name and run the command below to start a project:
npx create-nullstack-app project-name\n\nChange directory to the generated folder:
\ncd project-name\n\nInstall the dependencies:
\nnpm install\n\nStart the application in development mode:
\nnpm start\n\nThe following folders and files will be generated:
\nThis is the Webpack entry point.
\nUsually, you don't have to touch this file, but it is a convenient place to import global dependencies like CSS frameworks.
\nThis folder will contain the actual source code of your application.
\nThis is your application main file.
\n\n\n✨ Learn more about the njs file extension.
\n
The start function will be automatically called once when you run npm start, use it to populate your server context with things like database, settings, and secrets.
\n\n✨ Learn more about the application startup.
\n
This is an empty file just to demonstrate that you can use SCSS with Nullstack.
\nIt is a good practice to import a style file in a component with the same name.
\n\n\n✨ Learn more about styles.
\n
Every file in here will be available to anyone from the domain root.
\nBy default create-nullstack-app generates the icons required for your manifest.json and images for OG meta tags.
\n\n✨ Learn more about manifest.json.
\n
Be sure to replace these images with your project identity.
\nThis is the compiled result of your application in development mode.
\n\n\n🔥 Do not touch this folder
\n
This is the compiled result of your application in production mode.
\n\n\n🔥 Do not touch this folder
\n
\n\n✨ Learn more about how to deploy a Nullstack application.
\n
Warned on npx issues like #100, #110 and #143, it has an error when trying to resolve the path to his cache folder when contains spaces.
If this happens to you, our recommendations are:
\nUsing downloaded as you normally would with npm:
npm i -g create-nullstack-app\ncreate-nullstack-app project-name\nor, change the cache folder directory, as stated here and here:
\nFirstName with the one used on your path and run:npm config set cache \"C:\\Users\\FirstName~1\\AppData\\Roaming\\npm-cache\" --global\n\nnpm config set cache C:\\tmp\\nodejs\\npm-cache --global\n⚔ Create your first renderable component.
\n","description":"Create full-stack javascript applications within seconds"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Getting Started - Nullstack","description":"Create full-stack javascript applications within seconds"}} \ No newline at end of file diff --git a/docs/hero.svg b/docs/hero.svg deleted file mode 100644 index dc7dfffe..00000000 --- a/docs/hero.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/how-to-deploy-a-nullstack-application.html b/docs/how-to-deploy-a-nullstack-application.html deleted file mode 100644 index 729e8145..00000000 --- a/docs/how-to-deploy-a-nullstack-application.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - -With Nullstack it's easy to have your application up and running in production mode.
---🐱💻 stonks
-
Nullstack compiles your code and all your dependencies using Webpack.
-The output of the compilation is moved to the .production folder and is the only folder besides public that needs to be moved into the host machine.
-If you have project.cdn set you must move the public folder to the actual cdn.
--💡 It is important that the .production folder is present for environment detection
-
The host machine must have at least node v8.10.0 installed.
-You don't have to "npm install" in the host machine.
---✨ You can configure the environment using
-settingsandsecrets
To start the server just run:
-node .production/server.js
-
---✨ It is recommend the usage of a process manager like PM2
-
After you generate a static site, all you have to do is move the output folder to any host machine capable of serving HTML.
---🎉 Congratulations. You are done with the advanced concepts!
-
⚔ Learn how to use MongoDB with Nullstack.
-With Nullstack it's easy to have your application up and running in production mode.
---🐱💻 stonks
-
Nullstack compiles your code and all your dependencies using Webpack.
-The output of the compilation is moved to the .production folder and is the only folder besides public that needs to be moved into the host machine.
-If you have project.cdn set you must move the public folder to the actual cdn.
--💡 It is important that the .production folder is present for environment detection
-
The host machine must have at least node v8.10.0 installed.
-You don't have to "npm install" in the host machine.
---✨ You can configure the environment using
-settingsandsecrets
To start the server just run:
-node .production/server.js
-
---✨ It is recommend the usage of a process manager like PM2
-
After you generate a static site, all you have to do is move the output folder to any host machine capable of serving HTML.
---🎉 Congratulations. You are done with the advanced concepts!
-
⚔ Learn how to use MongoDB with Nullstack.
-With Nullstack it's easy to have your application up and running in production mode.
\n\n\n🐱💻 stonks
\n
Nullstack compiles your code and all your dependencies using Webpack.
\nThe output of the compilation is moved to the .production folder and is the only folder besides public that needs to be moved into the host machine.
\nIf you have project.cdn set you must move the public folder to the actual cdn.
\n\n💡 It is important that the .production folder is present for environment detection
\n
The host machine must have at least node v8.10.0 installed.
\nYou don't have to "npm install" in the host machine.
\n\n\n✨ You can configure the environment using
\nsettingsandsecrets
To start the server just run:
\nnode .production/server.js\n\n\n\n✨ It is recommend the usage of a process manager like PM2
\n
After you generate a static site, all you have to do is move the output folder to any host machine capable of serving HTML.
\n\n\n🎉 Congratulations. You are done with the advanced concepts!
\n
⚔ Learn how to use MongoDB with Nullstack.
\n","description":"With Nullstack it's easy to have your application up and running in production mode"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"How to Deploy - Nullstack","description":"With Nullstack it's easy to have your application up and running in production mode"}} \ No newline at end of file diff --git a/docs/how-to-use-facebook-pixel-with-nullstack.html b/docs/how-to-use-facebook-pixel-with-nullstack.html deleted file mode 100644 index 37a08447..00000000 --- a/docs/how-to-use-facebook-pixel-with-nullstack.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - -According to developers.facebook.com:
-"The Facebook pixel is a snippet of JavaScript code that allows you to track visitor activity on your website."
-You can take advantage of the context and custom events to create a component that dynamically sends Pixel events.
-Facebook's Pixel can only be called after hydrate to ensure it is running in the client.
import Nullstack from 'nullstack';
-
-class FacebookPixel extends Nullstack {
-
- async hydrate({page, id}) {
- ! function(f, b, e, v, n, t, s) {
- if (f.fbq) return;
- n = f.fbq = function() {
- n.callMethod ?
- n.callMethod.apply(n, arguments) : n.queue.push(arguments)
- };
- if (!f._fbq) f._fbq = n;
- n.push = n;
- n.loaded = !0;
- n.version = '2.0';
- n.queue = [];
- t = b.createElement(e);
- t.async = !0;
- t.src = v;
- s = b.getElementsByTagName(e)[0];
- s.parentNode.insertBefore(t, s)
- }(window, document, 'script',
- 'https://connect.facebook.net/en_US/fbevents.js');
- fbq('init', id);
- fbq('track', 'PageView');
- window.addEventListener(page.event, () => {
- fbq('init', id);
- fbq('track', 'PageView');
- })
- }
-}
-
-export default FacebookPixel;
-
-import Nullstack from 'nullstack';
-import FacebookPixel from './FacebookPixel';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <FacebookPixel id="REPLACE_WITH_YOUR_FACEBOOK_PIXEL_ID" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-Alternatively, you can install nullstack-facebook-pixel as a dependency:
-npm install nullstack-facebook-pixel
-
-import Nullstack from 'nullstack';
-import FacebookPixel from 'nullstack-facebook-pixel';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <FacebookPixel id="REPLACE_WITH_YOUR_FACEBOOK_PIXEL_ID" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
---🎉 Congratulations. You are done with the documentation!
-
⚔ If you want to see this more examples please open an issue on github.
-According to developers.facebook.com:
-"The Facebook pixel is a snippet of JavaScript code that allows you to track visitor activity on your website."
-You can take advantage of the context and custom events to create a component that dynamically sends Pixel events.
-Facebook's Pixel can only be called after hydrate to ensure it is running in the client.
import Nullstack from 'nullstack';
-
-class FacebookPixel extends Nullstack {
-
- async hydrate({page, id}) {
- ! function(f, b, e, v, n, t, s) {
- if (f.fbq) return;
- n = f.fbq = function() {
- n.callMethod ?
- n.callMethod.apply(n, arguments) : n.queue.push(arguments)
- };
- if (!f._fbq) f._fbq = n;
- n.push = n;
- n.loaded = !0;
- n.version = '2.0';
- n.queue = [];
- t = b.createElement(e);
- t.async = !0;
- t.src = v;
- s = b.getElementsByTagName(e)[0];
- s.parentNode.insertBefore(t, s)
- }(window, document, 'script',
- 'https://connect.facebook.net/en_US/fbevents.js');
- fbq('init', id);
- fbq('track', 'PageView');
- window.addEventListener(page.event, () => {
- fbq('init', id);
- fbq('track', 'PageView');
- })
- }
-}
-
-export default FacebookPixel;
-
-import Nullstack from 'nullstack';
-import FacebookPixel from './FacebookPixel';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <FacebookPixel id="REPLACE_WITH_YOUR_FACEBOOK_PIXEL_ID" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-Alternatively, you can install nullstack-facebook-pixel as a dependency:
-npm install nullstack-facebook-pixel
-
-import Nullstack from 'nullstack';
-import FacebookPixel from 'nullstack-facebook-pixel';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <FacebookPixel id="REPLACE_WITH_YOUR_FACEBOOK_PIXEL_ID" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
---🎉 Congratulations. You are done with the documentation!
-
⚔ If you want to see this more examples please open an issue on github.
-According to developers.facebook.com:
\n"The Facebook pixel is a snippet of JavaScript code that allows you to track visitor activity on your website."
\nYou can take advantage of the context and custom events to create a component that dynamically sends Pixel events.
\nFacebook's Pixel can only be called after hydrate to ensure it is running in the client.
import Nullstack from 'nullstack';\n\nclass FacebookPixel extends Nullstack {\n\n async hydrate({page, id}) {\n ! function(f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function() {\n n.callMethod ?\n n.callMethod.apply(n, arguments) : n.queue.push(arguments)\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s)\n }(window, document, 'script',\n 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', id);\n fbq('track', 'PageView');\n window.addEventListener(page.event, () => {\n fbq('init', id);\n fbq('track', 'PageView');\n })\n }\n}\n\nexport default FacebookPixel;\n\nimport Nullstack from 'nullstack';\nimport FacebookPixel from './FacebookPixel';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <FacebookPixel id=\"REPLACE_WITH_YOUR_FACEBOOK_PIXEL_ID\" />\n </main>\n )\n }\n\n\n}\n\nexport default Application;\n\nAlternatively, you can install nullstack-facebook-pixel as a dependency:
\nnpm install nullstack-facebook-pixel\n\nimport Nullstack from 'nullstack';\nimport FacebookPixel from 'nullstack-facebook-pixel';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <FacebookPixel id=\"REPLACE_WITH_YOUR_FACEBOOK_PIXEL_ID\" />\n </main>\n )\n }\n\n\n}\n\nexport default Application;\n\n\n\n🎉 Congratulations. You are done with the documentation!
\n
⚔ If you want to see this more examples please open an issue on github.
\n","description":"Take advantage of the [context](/context) and [custom events](/context-page) to create a component that dynamically sends Pixel events"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Facebook's Pixel - Nullstack","description":"Take advantage of the [context](/context) and [custom events](/context-page) to create a component that dynamically sends Pixel events"}} \ No newline at end of file diff --git a/docs/how-to-use-google-analytics-with-nullstack.html b/docs/how-to-use-google-analytics-with-nullstack.html deleted file mode 100644 index 9d692c4a..00000000 --- a/docs/how-to-use-google-analytics-with-nullstack.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - -According to analytics.google.com:
-"Google Analytics lets you measure your advertising ROI as well as track your Flash, video, and social networking sites and applications."
-You can take advantage of the context and custom events to create a component that dynamically sends GTAG events.
-GTAG can only be called after hydrate to ensure it is running in the client.
import Nullstack from 'nullstack';
-
-class GoogleAnalytics extends Nullstack {
-
- hydrate({router, page, id}) {
- window.dataLayer = window.dataLayer || [];
- function gtag(){
- dataLayer.push(arguments);
- }
- gtag('js', new Date());
- gtag('config', id, {
- page_title: page.title,
- page_path: router.url
- });
- window.addEventListener(page.event, () => {
- gtag('event', 'page_view', {
- page_title: page.title,
- page_path: router.url
- })
- })
- }
-
- render({id}) {
- return (
- <script
- async
- src={`https://www.googletagmanager.com/gtag/js?id=${id}`}
- />
- )
- }
-
-}
-
-export default GoogleAnalytics;
-
-import Nullstack from 'nullstack';
-import GoogleAnalytics from './GoogleAnalytics';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <GoogleAnalytics id="REPLACE_WITH_YOUR_GOOGLE_ANALYTICS_ID" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-Alternatively, you can install nullstack-google-analytics as a dependency:
-npm install nullstack-google-analytics
-
-import Nullstack from 'nullstack';
-import GoogleAnalytics from 'nullstack-google-analytics';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <GoogleAnalytics id="REPLACE_WITH_YOUR_GOOGLE_ANALYTICS_ID" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-According to analytics.google.com:
-"Google Analytics lets you measure your advertising ROI as well as track your Flash, video, and social networking sites and applications."
-You can take advantage of the context and custom events to create a component that dynamically sends GTAG events.
-GTAG can only be called after hydrate to ensure it is running in the client.
import Nullstack from 'nullstack';
-
-class GoogleAnalytics extends Nullstack {
-
- hydrate({router, page, id}) {
- window.dataLayer = window.dataLayer || [];
- function gtag(){
- dataLayer.push(arguments);
- }
- gtag('js', new Date());
- gtag('config', id, {
- page_title: page.title,
- page_path: router.url
- });
- window.addEventListener(page.event, () => {
- gtag('event', 'page_view', {
- page_title: page.title,
- page_path: router.url
- })
- })
- }
-
- render({id}) {
- return (
- <script
- async
- src={`https://www.googletagmanager.com/gtag/js?id=${id}`}
- />
- )
- }
-
-}
-
-export default GoogleAnalytics;
-
-import Nullstack from 'nullstack';
-import GoogleAnalytics from './GoogleAnalytics';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <GoogleAnalytics id="REPLACE_WITH_YOUR_GOOGLE_ANALYTICS_ID" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-Alternatively, you can install nullstack-google-analytics as a dependency:
-npm install nullstack-google-analytics
-
-import Nullstack from 'nullstack';
-import GoogleAnalytics from 'nullstack-google-analytics';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <GoogleAnalytics id="REPLACE_WITH_YOUR_GOOGLE_ANALYTICS_ID" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-According to analytics.google.com:
\n"Google Analytics lets you measure your advertising ROI as well as track your Flash, video, and social networking sites and applications."
\nYou can take advantage of the context and custom events to create a component that dynamically sends GTAG events.
\nGTAG can only be called after hydrate to ensure it is running in the client.
import Nullstack from 'nullstack';\n\nclass GoogleAnalytics extends Nullstack {\n\n hydrate({router, page, id}) {\n window.dataLayer = window.dataLayer || [];\n function gtag(){\n dataLayer.push(arguments);\n }\n gtag('js', new Date());\n gtag('config', id, {\n page_title: page.title,\n page_path: router.url\n });\n window.addEventListener(page.event, () => {\n gtag('event', 'page_view', {\n page_title: page.title,\n page_path: router.url\n })\n })\n }\n \n render({id}) {\n return (\n <script \n async\n src={`https://www.googletagmanager.com/gtag/js?id=${id}`}\n />\n )\n }\n\n}\n\nexport default GoogleAnalytics;\n\nimport Nullstack from 'nullstack';\nimport GoogleAnalytics from './GoogleAnalytics';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <GoogleAnalytics id=\"REPLACE_WITH_YOUR_GOOGLE_ANALYTICS_ID\" />\n </main>\n )\n }\n\n\n}\n\nexport default Application;\n\nAlternatively, you can install nullstack-google-analytics as a dependency:
\nnpm install nullstack-google-analytics\n\nimport Nullstack from 'nullstack';\nimport GoogleAnalytics from 'nullstack-google-analytics';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <GoogleAnalytics id=\"REPLACE_WITH_YOUR_GOOGLE_ANALYTICS_ID\" />\n </main>\n )\n }\n\n\n}\n\nexport default Application;\n\n⚔ Learn how to use Facebook Pixel with Nullstack.
\n","description":"Take advantage of the context and custom events to create a component that dynamically sends GTAG events"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Google Analytics - Nullstack","description":"Take advantage of the context and custom events to create a component that dynamically sends GTAG events"}} \ No newline at end of file diff --git a/docs/how-to-use-mongodb-with-nullstack.html b/docs/how-to-use-mongodb-with-nullstack.html deleted file mode 100644 index 6d808877..00000000 --- a/docs/how-to-use-mongodb-with-nullstack.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - -According to mongodb.com:
-"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era."
-You can use any database with Nullstack, but the javascript integration and flexibility of MongoDB looks especially good with Nullstack applications.
-Install the MongoDB driver from npm:
-npm install mongodb
-
-Configure the database credentials using secrets.
The last step is to simply assign the database connection to the server context.
-import Nullstack from 'nullstack';
-import {MongoClient} from 'mongodb';
-
-class Application extends Nullstack {
-
- static async start(context) {
- const {secrets} = context;
- secrets.development.databaseHost = 'mongodb://localhost:27017/dbname';
- secrets.databaseName = 'dbname';
- await this.startDatabase(context);
- }
-
- static async startDatabase(context) {
- const {secrets} = context;
- const databaseClient = new MongoClient(secrets.databaseHost);
- await databaseClient.connect();
- context.database = await databaseClient.db(secrets.databaseName);
- }
-
-}
-
-export default Application;
-
-The example above will make the database key available to all your server functions.
import Nullstack from 'nullstack';
-
-class BooksList extends Nullstack {
-
- books = [];
-
- static async getBooks({database}) {
- return await database.collection('books').find().toArray();
- }
-
- async initiate() {
- this.books = await this.getBooks();
- }
-
- // ...
-
-}
-
-export default BooksList;
-
-According to mongodb.com:
-"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era."
-You can use any database with Nullstack, but the javascript integration and flexibility of MongoDB looks especially good with Nullstack applications.
-Install the MongoDB driver from npm:
-npm install mongodb
-
-Configure the database credentials using secrets.
The last step is to simply assign the database connection to the server context.
-import Nullstack from 'nullstack';
-import {MongoClient} from 'mongodb';
-
-class Application extends Nullstack {
-
- static async start(context) {
- const {secrets} = context;
- secrets.development.databaseHost = 'mongodb://localhost:27017/dbname';
- secrets.databaseName = 'dbname';
- await this.startDatabase(context);
- }
-
- static async startDatabase(context) {
- const {secrets} = context;
- const databaseClient = new MongoClient(secrets.databaseHost);
- await databaseClient.connect();
- context.database = await databaseClient.db(secrets.databaseName);
- }
-
-}
-
-export default Application;
-
-The example above will make the database key available to all your server functions.
import Nullstack from 'nullstack';
-
-class BooksList extends Nullstack {
-
- books = [];
-
- static async getBooks({database}) {
- return await database.collection('books').find().toArray();
- }
-
- async initiate() {
- this.books = await this.getBooks();
- }
-
- // ...
-
-}
-
-export default BooksList;
-
-According to mongodb.com:
\n"MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era."
\nYou can use any database with Nullstack, but the javascript integration and flexibility of MongoDB looks especially good with Nullstack applications.
\nInstall the MongoDB driver from npm:
\nnpm install mongodb\n\nConfigure the database credentials using secrets.
The last step is to simply assign the database connection to the server context.
\nimport Nullstack from 'nullstack';\nimport {MongoClient} from 'mongodb';\n\nclass Application extends Nullstack {\n\n static async start(context) {\n const {secrets} = context;\n secrets.development.databaseHost = 'mongodb://localhost:27017/dbname';\n secrets.databaseName = 'dbname';\n await this.startDatabase(context);\n }\n\n static async startDatabase(context) {\n const {secrets} = context;\n const databaseClient = new MongoClient(secrets.databaseHost);\n await databaseClient.connect();\n context.database = await databaseClient.db(secrets.databaseName);\n }\n\n}\n\nexport default Application;\n\nThe example above will make the database key available to all your server functions.
import Nullstack from 'nullstack';\n\nclass BooksList extends Nullstack {\n\n books = [];\n\n static async getBooks({database}) {\n return await database.collection('books').find().toArray();\n }\n\n async initiate() {\n this.books = await this.getBooks();\n }\n\n // ...\n\n}\n\nexport default BooksList;\n\n⚔ Learn how to use Google Analytics with Nullstack.
\n","description":"You can use any database with Nullstack, but the javascript integration and flexibility of MongoDB looks especially good with Nullstack applications"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"How to use MongoDB - Nullstack","description":"You can use any database with Nullstack, but the javascript integration and flexibility of MongoDB looks especially good with Nullstack applications"}} \ No newline at end of file diff --git a/docs/icon-128x128.png b/docs/icon-128x128.png deleted file mode 100644 index e96fe8b5..00000000 Binary files a/docs/icon-128x128.png and /dev/null differ diff --git a/docs/icon-144x144.png b/docs/icon-144x144.png deleted file mode 100644 index a87f2a70..00000000 Binary files a/docs/icon-144x144.png and /dev/null differ diff --git a/docs/icon-152x152.png b/docs/icon-152x152.png deleted file mode 100644 index 10b23e29..00000000 Binary files a/docs/icon-152x152.png and /dev/null differ diff --git a/docs/icon-180x180.png b/docs/icon-180x180.png deleted file mode 100644 index 252b3a4f..00000000 Binary files a/docs/icon-180x180.png and /dev/null differ diff --git a/docs/icon-192x192.png b/docs/icon-192x192.png deleted file mode 100644 index 450ca4ca..00000000 Binary files a/docs/icon-192x192.png and /dev/null differ diff --git a/docs/icon-384x384.png b/docs/icon-384x384.png deleted file mode 100644 index c50c7037..00000000 Binary files a/docs/icon-384x384.png and /dev/null differ diff --git a/docs/icon-512x512.png b/docs/icon-512x512.png deleted file mode 100644 index db7461c0..00000000 Binary files a/docs/icon-512x512.png and /dev/null differ diff --git a/docs/icon-72x72.png b/docs/icon-72x72.png deleted file mode 100644 index 58aaf4cd..00000000 Binary files a/docs/icon-72x72.png and /dev/null differ diff --git a/docs/icon-96x96.png b/docs/icon-96x96.png deleted file mode 100644 index a6dd92a8..00000000 Binary files a/docs/icon-96x96.png and /dev/null differ diff --git a/docs/image-1200x630.png b/docs/image-1200x630.png deleted file mode 100644 index 03da34b6..00000000 Binary files a/docs/image-1200x630.png and /dev/null differ diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index c718e73d..00000000 --- a/docs/index.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - -for one-dev armies
Nullstack is a full-stack framework for building progressive web applications.
It connects a stateful UI layer to specialized microservices in the same component using vanilla javascript.
Focus on solving your business logic instead of writing glue code.
Nullstack generates SEO ready HTML optimized for the first paint of your route in a single request using local functions with zero javascript dependencies in the client bundle.
After hydration, requests will fetch JSON from an automatically generated API off server functions, update the application state, and rerender the page.
You can even use Nullstack to generate lightning-fast static websites that serve HTML and become a single page application using an automatically generated static API .
Nullstack is not another part of your stack, it is your stack
Your application can be exported from back-end to front-end as a component and mounted into another application
import Nullstack from 'nullstack';
-
-class ProductList extends Nullstack {
-
- products = [];
-
- static async getProducts({ database }) {
- const [products] = await database.query(
- 'SELECT * FROM products'
- );
- return products;
- }
-
- async initiate() {
- this.products = await this.getProducts();
- }
-
- static async deleteProduct({ database, id }) {
- await database.query(
- 'DELETE FROM products WHERE id=?',
- [id]
- );
- }
-
- async remove({ id }) {
- await this.deleteProduct({ id });
- await this.initiate();
- }
-
- renderProduct({ id, name }) {
- return (
- <li>
- <button onclick={this.remove} id={id}>
- {name}
- </button>
- </li>
- )
- }
-
- render() {
- return (
- <ul>
- {this.products.map((product) => (
- <Product {...product} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default ProductList;import Nullstack from 'nullstack';
-
-class ProductForm extends Nullstack {
-
- name = '';
- price = 0;
-
- static async getProductById({ database, id }) {
- const [products] = await database.query(
- 'SELECT * FROM products WHERE id=? LIMIT 1',
- [id]
- );
- return products[0];
- }
-
- async initiate({ params }) {
- const product = await this.getProductById({
- id: params.id
- });
- this.name = product.name;
- this.price = product.price;
- }
-
- static async updateProduct({ database, name, price, id }) {
- await database.query(
- 'UPDATE products SET name=?, price=? WHERE id=?',
- [name, price, id]
- );
- }
-
- async submit({ router, params }) {
- await this.updateProduct({
- id: params.id,
- name: this.name,
- price: this.price
- });
- router.url = '/products';
- }
-
- render() {
- return (
- <form onsubmit={this.submit}>
- <input class="form-control" bind={this.name} />
- <input type="number" step=".01" bind={this.price} />
- <button>Submit</button>
- </form>
- )
- }
-
-}
-
-export default ProductForm;The example above is the complete code of a product list and edit form without hiding a single line.
Both components invoke server functions to access a MySQL database inside JavaScript without you having to think about APIs
Nullstack features have been extracted from real life projects with convenience and consistency in mind
import Nullstack from 'nullstack';
-
-class Controlled extends Nullstack {
-
- count = 0;
-
- increment({delta}) {
- this.count += delta;
- }
-
- render() {
- return (
- <div>
- <button onclick={this.increment} delta={-1}>
- {this.count}
- </button>
- <span> {this.count} </span>
- <button onclick={this.increment} delta={1}>
- {this.count}
- </button>
- </div>
- )
- }
-
-}
-
-export default Controlled;import Nullstack from 'nullstack';
-
-class Binding extends Nullstack {
-
- number = 1;
- boolean = true;
-
- object = {number: 1};
- array = ['a', 'b', 'c'];
-
- render({params}) {
- return (
- <form>
- <input bind={this.number} />
- <input bind={this.boolean} type="checkbox" />
- <input bind={this.object.number} />
- {this.array.map((value, index) => (
- <input bind={this.array[index]} />
- ))}
- <input bind={params.page} />
- </form>
- )
- }
-
-}
-
-export default Binding;import Nullstack from 'nullstack';
-
-class Routes extends Nullstack {
-
- renderPost({params}) {
- return (
- <div>
- <div route="/post/getting-started">
- npx create-nullstack-app name
- </div>
- <div route="*"> {params.slug} </div>
- </div>
- )
- }
-
- render() {
- return (
- <div>
- <Post route="/post/:slug" />
- <a href="/post/hello-world"> Welcome </a>
- </div>
- )
- }
-
-}
-
-export default Routes;import Nullstack from 'nullstack';
-
-class Lifecycle extends Nullstack {
-
- prepare({environment}) {
- const {server, client} = environment;
- }
-
- async initiate({environment}) {
- const {server, client} = environment;
- }
-
- async hydrate({environment}) {
- const {client} = environment;
- }
-
- async update({environment}) {
- const {client} = environment;
- }
-
- async terminate({environment}) {
- const {client} = environment;
- }
-
-}
-
-export default Lifecycle;Nullstack cares about making its content as direct to the point and easy to understand as possible
Every project starts small and becomes complex over time. Scale as you go, no matter the size of the team.
No compromises, no enforcements.Development of both back and front ends of a feature in the same component in an organized way with ease of overview.
True componentization and code reusability.Takes advantage of any isomorphic vanilla Javascript package made throughout history.
All of your application speaks the same language.The horizontal structure, as opposed to a hierarchical one, makes it a lot easier to move resources around.
Flexibility over bureaucracy.objectIt gives you information about the instance lifecycle and it's unique key.
Each instance receives its own self object.
The following keys are available in the object:
-key: stringWhen a lifecycle method is resolved, even if not declared, an equivalent key is set to true in self.
If the component was server-side rendered the prerendered key will remain true until it is terminated.
The element key points to the DOM selector and is only guaranteed to exist when hydrate is being called since prepare and initiate could run in the server.
--💡 Do not use
-elementto guess the environment, instead use theenvironmentfor that.
Observing self is a nice way to avoid giving placeholder information to the end-user.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- // ...
-
- async initiate() {
- this.price = await this.getPrice();
- }
-
- async hydrate({self}) {
- self.element.querySelector('input').focus();
- }
-
- render({self}) {
- if(!self.prerendered && !self.initiated) return false;
- return (
- <form>
- <input type="number" bind={this.price} />
- <button disabled={!self.hydrated}>
- Save
- </button>
- </form>
- )
- }
-
-}
-
-export default Page;
-
---💡 Components that get optimized into functional components have no access to
-self.
stringIt allows you to persist the instance when it moves in the dom.
-You can declare one key per instance.
--💡 If you do not declare a
-keynullstack will generate one based on dom depth.
--🔥 Keys cannot start with "_." to avoid conflicts with Nullstack generated keys
-
Keys must be globally unique since the component could move anywhere around the dom and not only between its siblings.
-Keys are useful to preserve state in stateful components when you move them in the dom.
-This is especially useful for dynamically sized lists that invoke components.
-import Nullstack from 'nullstack';
-import Item from './Item';
-
-class List extends Nullstack {
-
- // ...
-
- async initiate() {
- this.items = await this.getItems();
- }
-
- render({self}) {
- const componentKey = self.key;
- return (
- <ul>
- {this.items.map((item) => (
- <Item key={`${componentKey}-${item.id}`} {...item} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default Page;
-
-You can also use keys to share the instance between two elements.
-Only the first encounter of the key will run its lifecycle.
import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render({amount}) {
- return (
- <div>
- <button onclick={{count: this.count+1}}>
- {this.count} x {amount} = {this.count * amount}
- </button>
- </div>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- render() {
- return (
- <main>
- <Counter key="a" amount={1} />
- <Counter key="b" amount={2} />
- <Counter key="b" amount={3} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-stringIt allows you to persist the instance when it moves in the dom.
-You can declare one key per instance.
---💡 If you do not declare a key nullstack will generate one based on dom depth.
-
--🔥 Keys cannot start with "_." to avoid conflicts with Nullstack generated keys
-
Keys must be globally unique since the component could move anywhere around the dom and not only between its siblings.
-Keys are useful to preserve state in stateful components when you move them in the dom.
-This is especially useful for dynamically sized lists that invoke components.
-import Nullstack from 'nullstack';
-import Item from './Item';
-
-class List extends Nullstack {
-
- // ...
-
- async initiate() {
- this.items = await this.getItems();
- }
-
- render({self}) {
- const componentKey = self.key;
- return (
- <ul>
- {this.items.map((item) => (
- <Item key={`${componentKey}-${item.id}`} {...item} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default Page;
-
-You can also use keys to share the instance between two elements.
-Only the first encounter of the key will run its lifecycle
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render({amount}) {
- return (
- <div>
- <button onclick={{count: this.count+1}}>
- {this.count} x {amount} = {this.count * amount}
- </button>
- </div>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- render() {
- return (
- <main>
- <Counter key="a" amount={1} />
- <Counter key="b" amount={2} />
- <Counter key="b" amount={3} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-⚔ Learn about the server request and response.
-objectIt gives you information about the instance lifecycle and it's unique key.
Each instance receives its own self object.
The following keys are available in the object:
-key: stringWhen a lifecycle method is resolved, even if not declared, an equivalent key is set to true in self.
If the component was server-side rendered the prerendered key will remain true until it is terminated.
The element key points to the DOM selector and is only guaranteed to exist when hydrate is being called since prepare and initiate could run in the server.
--💡 Do not use
-elementto guess the environment, instead use theenvironmentfor that.
Observing self is a nice way to avoid giving placeholder information to the end-user.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- // ...
-
- async initiate() {
- this.price = await this.getPrice();
- }
-
- async hydrate({self}) {
- self.element.querySelector('input').focus();
- }
-
- render({self}) {
- if(!self.prerendered && !self.initiated) return false;
- return (
- <form>
- <input type="number" bind={this.price} />
- <button disabled={!self.hydrated}>
- Save
- </button>
- </form>
- )
- }
-
-}
-
-export default Page;
-
---💡 Components that get optimized into functional components have no access to
-self.
stringIt allows you to persist the instance when it moves in the dom.
-You can declare one key per instance.
--💡 If you do not declare a
-keynullstack will generate one based on dom depth.
--🔥 Keys cannot start with "_." to avoid conflicts with Nullstack generated keys
-
Keys must be globally unique since the component could move anywhere around the dom and not only between its siblings.
-Keys are useful to preserve state in stateful components when you move them in the dom.
-This is especially useful for dynamically sized lists that invoke components.
-import Nullstack from 'nullstack';
-import Item from './Item';
-
-class List extends Nullstack {
-
- // ...
-
- async initiate() {
- this.items = await this.getItems();
- }
-
- render({self}) {
- const componentKey = self.key;
- return (
- <ul>
- {this.items.map((item) => (
- <Item key={`${componentKey}-${item.id}`} {...item} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default Page;
-
-You can also use keys to share the instance between two elements.
-Only the first encounter of the key will run its lifecycle.
import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render({amount}) {
- return (
- <div>
- <button onclick={{count: this.count+1}}>
- {this.count} x {amount} = {this.count * amount}
- </button>
- </div>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- render() {
- return (
- <main>
- <Counter key="a" amount={1} />
- <Counter key="b" amount={2} />
- <Counter key="b" amount={3} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-stringIt allows you to persist the instance when it moves in the dom.
-You can declare one key per instance.
---💡 If you do not declare a key nullstack will generate one based on dom depth.
-
--🔥 Keys cannot start with "_." to avoid conflicts with Nullstack generated keys
-
Keys must be globally unique since the component could move anywhere around the dom and not only between its siblings.
-Keys are useful to preserve state in stateful components when you move them in the dom.
-This is especially useful for dynamically sized lists that invoke components.
-import Nullstack from 'nullstack';
-import Item from './Item';
-
-class List extends Nullstack {
-
- // ...
-
- async initiate() {
- this.items = await this.getItems();
- }
-
- render({self}) {
- const componentKey = self.key;
- return (
- <ul>
- {this.items.map((item) => (
- <Item key={`${componentKey}-${item.id}`} {...item} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default Page;
-
-You can also use keys to share the instance between two elements.
-Only the first encounter of the key will run its lifecycle
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render({amount}) {
- return (
- <div>
- <button onclick={{count: this.count+1}}>
- {this.count} x {amount} = {this.count * amount}
- </button>
- </div>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- render() {
- return (
- <main>
- <Counter key="a" amount={1} />
- <Counter key="b" amount={2} />
- <Counter key="b" amount={3} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-⚔ Learn about the server request and response.
-objectIt gives you information about the instance lifecycle and it's unique key.
Each instance receives its own self object.
The following keys are available in the object:
\nkey: stringWhen a lifecycle method is resolved, even if not declared, an equivalent key is set to true in self.
If the component was server-side rendered the prerendered key will remain true until it is terminated.
The element key points to the DOM selector and is only guaranteed to exist when hydrate is being called since prepare and initiate could run in the server.
\n\n💡 Do not use
\nelementto guess the environment, instead use theenvironmentfor that.
Observing self is a nice way to avoid giving placeholder information to the end-user.
import Nullstack from 'nullstack';\n\nclass Page extends Nullstack {\n\n // ...\n\n async initiate() {\n this.price = await this.getPrice();\n }\n\n async hydrate({self}) {\n self.element.querySelector('input').focus();\n }\n \n render({self}) {\n if(!self.prerendered && !self.initiated) return false;\n return (\n <form> \n <input type=\"number\" bind={this.price} />\n <button disabled={!self.hydrated}> \n Save\n </button>\n </form>\n )\n }\n\n}\n\nexport default Page;\n\n\n\n💡 Components that get optimized into functional components have no access to
\nself.
stringIt allows you to persist the instance when it moves in the dom.
\nYou can declare one key per instance.
\n\n💡 If you do not declare a
\nkeynullstack will generate one based on dom depth.
\n\n🔥 Keys cannot start with "_." to avoid conflicts with Nullstack generated keys
\n
Keys must be globally unique since the component could move anywhere around the dom and not only between its siblings.
\nKeys are useful to preserve state in stateful components when you move them in the dom.
\nThis is especially useful for dynamically sized lists that invoke components.
\nimport Nullstack from 'nullstack';\nimport Item from './Item';\n\nclass List extends Nullstack {\n\n // ...\n\n async initiate() {\n this.items = await this.getItems();\n }\n \n render({self}) {\n const componentKey = self.key;\n return (\n <ul> \n {this.items.map((item) => (\n <Item key={`${componentKey}-${item.id}`} {...item} />\n ))}\n </ul>\n )\n }\n\n}\n\nexport default Page;\n\nYou can also use keys to share the instance between two elements.
\nOnly the first encounter of the key will run its lifecycle.
import Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n render({amount}) {\n return (\n <div>\n <button onclick={{count: this.count+1}}>\n {this.count} x {amount} = {this.count * amount}\n </button> \n </div>\n )\n }\n\n}\n\nexport default Counter;\n\nimport Nullstack from 'nullstack';\nimport Counter from './Counter';\n\nclass Application extends Nullstack {\n\n render() {\n return (\n <main>\n <Counter key=\"a\" amount={1} />\n <Counter key=\"b\" amount={2} />\n <Counter key=\"b\" amount={3} />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nstringIt allows you to persist the instance when it moves in the dom.
\nYou can declare one key per instance.
\n\n\n💡 If you do not declare a key nullstack will generate one based on dom depth.
\n
\n\n🔥 Keys cannot start with "_." to avoid conflicts with Nullstack generated keys
\n
Keys must be globally unique since the component could move anywhere around the dom and not only between its siblings.
\nKeys are useful to preserve state in stateful components when you move them in the dom.
\nThis is especially useful for dynamically sized lists that invoke components.
\nimport Nullstack from 'nullstack';\nimport Item from './Item';\n\nclass List extends Nullstack {\n\n // ...\n\n async initiate() {\n this.items = await this.getItems();\n }\n \n render({self}) {\n const componentKey = self.key;\n return (\n <ul> \n {this.items.map((item) => (\n <Item key={`${componentKey}-${item.id}`} {...item} />\n ))}\n </ul>\n )\n }\n\n}\n\nexport default Page;\n\nYou can also use keys to share the instance between two elements.
\nOnly the first encounter of the key will run its lifecycle
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n render({amount}) {\n return (\n <div>\n <button onclick={{count: this.count+1}}>\n {this.count} x {amount} = {this.count * amount}\n </button> \n </div>\n )\n }\n\n}\n\nexport default Counter;\n\nimport Nullstack from 'nullstack';\nimport Counter from './Counter';\n\nclass Application extends Nullstack {\n\n render() {\n return (\n <main>\n <Counter key=\"a\" amount={1} />\n <Counter key=\"b\" amount={2} />\n <Counter key=\"b\" amount={3} />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\n⚔ Learn about the server request and response.
\n","description":"The self object is a proxy in the Nullstack Context available in client and gives you information about the instance lifecycle"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Instance Self - Nullstack","description":"The self object is a proxy in the Nullstack Context available in client and gives you information about the instance lifecycle"}} \ No newline at end of file diff --git a/docs/manifest-9cdb5778f42a90a83e1427c9316c97d3.json b/docs/manifest-9cdb5778f42a90a83e1427c9316c97d3.json deleted file mode 100644 index 3b29c313..00000000 --- a/docs/manifest-9cdb5778f42a90a83e1427c9316c97d3.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"Nullstack","short_name":"Nullstack","theme_color":"#d22365","background_color":"#2d3748","display":"standalone","orientation":"portrait","scope":"/","start_url":"/","icons":[{"src":"/icon-72x72.png","sizes":"72x72","type":"image/png","purpose":"maskable any"},{"src":"/icon-96x96.png","sizes":"96x96","type":"image/png","purpose":"maskable any"},{"src":"/icon-128x128.png","sizes":"128x128","type":"image/png","purpose":"maskable any"},{"src":"/icon-144x144.png","sizes":"144x144","type":"image/png","purpose":"maskable any"},{"src":"/icon-152x152.png","sizes":"152x152","type":"image/png","purpose":"maskable any"},{"src":"/icon-180x180.png","sizes":"180x180","type":"image/png","purpose":"maskable any"},{"src":"/icon-192x192.png","sizes":"192x192","type":"image/png","purpose":"maskable any"},{"src":"/icon-384x384.png","sizes":"384x384","type":"image/png","purpose":"maskable any"},{"src":"/icon-512x512.png","sizes":"512x512","type":"image/png","purpose":"maskable any"}],"splash_pages":null} \ No newline at end of file diff --git a/docs/njs-file-extension.html b/docs/njs-file-extension.html deleted file mode 100644 index 8bbeecd6..00000000 --- a/docs/njs-file-extension.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - -Nullstack Javascript files let Webpack know which loaders to use at transpile time.
-NJS files must import Nullstack or one of its subclasses.
-If only a subclass is imported, a Nullstack import will be injected at transpile time.
-At transpile time JSX tags will be replaced with Nullstack.element.
This extension also allows Nullstack to make free transpile time optimizations like source injection.
---🔥 Each file must have only one class declaration.
-
--🐱💻 Bellow an example of a original .njs file.
-
import List from './List';
-import {readFileSync} from 'fs';
-
-class Tasks extends List {
-
- static async getTasks({limit}) {
- const json = readFileSync('tasks.json', 'utf-8');
- return JSON.parse(json).tasks.slice(0, limit);
- }
-
- prepare(context) {
- context.tasks = [];
- }
-
- async initiate(context) {
- context.tasks = await this.getTasks({limit: 10});
- }
-
- renderTask({task}) {
- return (
- <li>
- <input bind={task.description} />
- </li>
- )
- }
-
- render() {
- return (
- <main>
- <ul>
- {tasks.map((task) => <Task task={task} />)}
- </ul>
- </main>
- )
- }
-
-}
-
-export default Tasks;
-
---🐱💻 Bellow an example of the same transpiled .njs file.
-
import Nullstack from 'nullstack';
-import List from './List';
-
-class Tasks extends List {
-
- static hash = 'd493ac09d0d57574a30f136d31da455f';
-
- static getTasks = Nullstack.invoke('getTasks', 'd493ac09d0d57574a30f136d31da455f');
-
- prepare(context) {
- context.tasks = [];
- }
-
- async initiate(context) {
- context.tasks = await this.getTasks({limit: 10});
- }
-
- renderTask({task}) {
- return (
- <li>
- <input source={task} bind="description" />
- </li>
- )
- }
-
- render() {
- const Task = this.renderTask;
- return (
- <main>
- <ul>
- {tasks.map((task) => <Task task={task} />)}
- </ul>
- </main>
- )
- }
-
-}
-
-export default Tasks;
-
-⚔ Learn about server-side rendering.
-Nullstack Javascript files let Webpack know which loaders to use at transpile time.
-NJS files must import Nullstack or one of its subclasses.
-If only a subclass is imported, a Nullstack import will be injected at transpile time.
-At transpile time JSX tags will be replaced with Nullstack.element.
This extension also allows Nullstack to make free transpile time optimizations like source injection.
---🔥 Each file must have only one class declaration.
-
--🐱💻 Bellow an example of a original .njs file.
-
import List from './List';
-import {readFileSync} from 'fs';
-
-class Tasks extends List {
-
- static async getTasks({limit}) {
- const json = readFileSync('tasks.json', 'utf-8');
- return JSON.parse(json).tasks.slice(0, limit);
- }
-
- prepare(context) {
- context.tasks = [];
- }
-
- async initiate(context) {
- context.tasks = await this.getTasks({limit: 10});
- }
-
- renderTask({task}) {
- return (
- <li>
- <input bind={task.description} />
- </li>
- )
- }
-
- render() {
- return (
- <main>
- <ul>
- {tasks.map((task) => <Task task={task} />)}
- </ul>
- </main>
- )
- }
-
-}
-
-export default Tasks;
-
---🐱💻 Bellow an example of the same transpiled .njs file.
-
import Nullstack from 'nullstack';
-import List from './List';
-
-class Tasks extends List {
-
- static hash = 'd493ac09d0d57574a30f136d31da455f';
-
- static getTasks = Nullstack.invoke('getTasks', 'd493ac09d0d57574a30f136d31da455f');
-
- prepare(context) {
- context.tasks = [];
- }
-
- async initiate(context) {
- context.tasks = await this.getTasks({limit: 10});
- }
-
- renderTask({task}) {
- return (
- <li>
- <input source={task} bind="description" />
- </li>
- )
- }
-
- render() {
- const Task = this.renderTask;
- return (
- <main>
- <ul>
- {tasks.map((task) => <Task task={task} />)}
- </ul>
- </main>
- )
- }
-
-}
-
-export default Tasks;
-
-⚔ Learn about server-side rendering.
-Nullstack Javascript files let Webpack know which loaders to use at transpile time.
\nNJS files must import Nullstack or one of its subclasses.
\nIf only a subclass is imported, a Nullstack import will be injected at transpile time.
\nAt transpile time JSX tags will be replaced with Nullstack.element.
This extension also allows Nullstack to make free transpile time optimizations like source injection.
\n\n\n🔥 Each file must have only one class declaration.
\n
\n\n🐱💻 Bellow an example of a original .njs file.
\n
import List from './List';\nimport {readFileSync} from 'fs';\n\nclass Tasks extends List {\n\n static async getTasks({limit}) {\n const json = readFileSync('tasks.json', 'utf-8');\n return JSON.parse(json).tasks.slice(0, limit);\n }\n\n prepare(context) {\n context.tasks = [];\n }\n\n async initiate(context) {\n context.tasks = await this.getTasks({limit: 10});\n }\n\n renderTask({task}) {\n return (\n <li> \n <input bind={task.description} />\n </li>\n )\n }\n\n render() {\n return (\n <main>\n <ul>\n {tasks.map((task) => <Task task={task} />)}\n </ul>\n </main>\n )\n }\n\n}\n\nexport default Tasks;\n\n\n\n🐱💻 Bellow an example of the same transpiled .njs file.
\n
import Nullstack from 'nullstack';\nimport List from './List';\n\nclass Tasks extends List {\n\n static hash = 'd493ac09d0d57574a30f136d31da455f';\n\n static getTasks = Nullstack.invoke('getTasks', 'd493ac09d0d57574a30f136d31da455f');\n\n prepare(context) {\n context.tasks = [];\n }\n\n async initiate(context) {\n context.tasks = await this.getTasks({limit: 10});\n }\n\n renderTask({task}) {\n return (\n <li> \n <input source={task} bind=\"description\" />\n </li>\n )\n }\n\n render() {\n const Task = this.renderTask;\n return (\n <main>\n <ul>\n {tasks.map((task) => <Task task={task} />)}\n </ul>\n </main>\n )\n }\n\n}\n\nexport default Tasks;\n\n⚔ Learn about server-side rendering.
\n","description":"Nullstack Javascript files let Webpack know which loaders to use at transpile time"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"NJS File Extension - Nullstack","description":"Nullstack Javascript files let Webpack know which loaders to use at transpile time"}} \ No newline at end of file diff --git a/docs/nullachan.png b/docs/nullachan.png deleted file mode 100644 index 0f5ccd45..00000000 Binary files a/docs/nullachan.png and /dev/null differ diff --git a/docs/offline-9cdb5778f42a90a83e1427c9316c97d3.html b/docs/offline-9cdb5778f42a90a83e1427c9316c97d3.html deleted file mode 100644 index 4ddca07a..00000000 --- a/docs/offline-9cdb5778f42a90a83e1427c9316c97d3.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Perhaps you want to learn about how to make a 404 page with Nullstack?
-If you are looking for something else, you should read the documentation.
-Perhaps you want to learn about how to make a 404 page with Nullstack?
-If you are looking for something else, you should read the documentation.
-Perhaps you want to learn about how to make a 404 page with Nullstack?
\nIf you are looking for something else, you should read the documentation.
\n","description":"Sorry, this is not the page you are looking for.","status":404},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Page Not Found - Nullstack","description":"Sorry, this is not the page you are looking for."}} \ No newline at end of file diff --git a/docs/pt-br.html b/docs/pt-br.html deleted file mode 100644 index af0b34af..00000000 --- a/docs/pt-br.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - -para exércitos de um dev só
Nullstack é um framework full-stack para construir aplicações web progressivas.
Ele conecta uma camada de UI com estado a microserviços especializados no mesmo componente usando vanilla javascript.
Concentre-se em resolver sua lógica de negócios em vez de escrever código para interoperabilidade.
Nullstack gera HTML otimizado e com SEO pronto para o primeiro rascunho de sua rota em uma única requisição usando funções locais e com zero dependências javascript no cliente.
Após hidratação, requisições irão buscar JSON de uma API gerada automaticamente por funções do servidor, atualizar o estado da aplicação e renderizar a página novamente.
Você pode até usar o Nullstack para gerar sites estáticos ultra-rápidos que servem HTML e se tornam uma Single Page Application usando uma API estática gerada automaticamente.
Nullstack não é apenas outra parte de sua stack, mas sim a sua stack
Sua aplicação pode ser exportado do back-end para o front-end como um componente e montado em outra aplicação
import Nullstack from 'nullstack';
-
-class ProductList extends Nullstack {
-
- products = [];
-
- static async getProducts({ database }) {
- const [products] = await database.query(
- 'SELECT * FROM products'
- );
- return products;
- }
-
- async initiate() {
- this.products = await this.getProducts();
- }
-
- static async deleteProduct({ database, id }) {
- await database.query(
- 'DELETE FROM products WHERE id=?',
- [id]
- );
- }
-
- async remove({ id }) {
- await this.deleteProduct({ id });
- await this.initiate();
- }
-
- renderProduct({ id, name }) {
- return (
- <li>
- <button onclick={this.remove} id={id}>
- {name}
- </button>
- </li>
- )
- }
-
- render() {
- return (
- <ul>
- {this.products.map((product) => (
- <Product {...product} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default ProductList;import Nullstack from 'nullstack';
-
-class ProductForm extends Nullstack {
-
- name = '';
- price = 0;
-
- static async getProductById({ database, id }) {
- const [products] = await database.query(
- 'SELECT * FROM products WHERE id=? LIMIT 1',
- [id]
- );
- return products[0];
- }
-
- async initiate({ params }) {
- const product = await this.getProductById({
- id: params.id
- });
- this.name = product.name;
- this.price = product.price;
- }
-
- static async updateProduct({ database, name, price, id }) {
- await database.query(
- 'UPDATE products SET name=?, price=? WHERE id=?',
- [name, price, id]
- );
- }
-
- async submit({ router, params }) {
- await this.updateProduct({
- id: params.id,
- name: this.name,
- price: this.price
- });
- router.url = '/products';
- }
-
- render() {
- return (
- <form onsubmit={this.submit}>
- <input class="form-control" bind={this.name} />
- <input type="number" step=".01" bind={this.price} />
- <button>Submit</button>
- </form>
- )
- }
-
-}
-
-export default ProductForm;O exemplo acima é o código completo de uma listagem de produtos e um formulário de edição sem esconder nenhuma linha.
Ambos os componentes invocam funções de servidor para ter acesso ao banco de dados MySQL no meio do JavaScript sem você ter que pensar em APIs.
Os recursos do Nullstack foram extraídos de projetos da vida real com conveniência e consistência em mente
import Nullstack from 'nullstack';
-
-class Controlled extends Nullstack {
-
- count = 0;
-
- increment({delta}) {
- this.count += delta;
- }
-
- render() {
- return (
- <div>
- <button onclick={this.increment} delta={-1}>
- {this.count}
- </button>
- <span> {this.count} </span>
- <button onclick={this.increment} delta={1}>
- {this.count}
- </button>
- </div>
- )
- }
-
-}
-
-export default Controlled;import Nullstack from 'nullstack';
-
-class Binding extends Nullstack {
-
- number = 1;
- boolean = true;
-
- object = {number: 1};
- array = ['a', 'b', 'c'];
-
- render({params}) {
- return (
- <form>
- <input bind={this.number} />
- <input bind={this.boolean} type="checkbox" />
- <input bind={this.object.number} />
- {this.array.map((value, index) => (
- <input bind={this.array[index]} />
- ))}
- <input bind={params.page} />
- </form>
- )
- }
-
-}
-
-export default Binding;import Nullstack from 'nullstack';
-
-class Routes extends Nullstack {
-
- renderPost({params}) {
- return (
- <div>
- <div route="/post/getting-started">
- npx create-nullstack-app name
- </div>
- <div route="*"> {params.slug} </div>
- </div>
- )
- }
-
- render() {
- return (
- <div>
- <Post route="/post/:slug" />
- <a href="/post/hello-world"> Welcome </a>
- </div>
- )
- }
-
-}
-
-export default Routes;import Nullstack from 'nullstack';
-
-class Lifecycle extends Nullstack {
-
- prepare({environment}) {
- const {server, client} = environment;
- }
-
- async initiate({environment}) {
- const {server, client} = environment;
- }
-
- async hydrate({environment}) {
- const {client} = environment;
- }
-
- async update({environment}) {
- const {client} = environment;
- }
-
- async terminate({environment}) {
- const {client} = environment;
- }
-
-}
-
-export default Lifecycle;Nullstack se preocupa em tornar seu conteúdo o mais direto ao ponto e fácil de entender quanto possível
Cada projeto começa pequeno e se torna complexo com o tempo. Escale conforme avança, não importa o tamanho da equipe.
Sem compromissos, sem imposições.Desenvolvimento de back e front end de um recurso no mesmo componente de forma organizada com facilidade de visão geral.
Verdadeira componentização e reutilização de código.Tira proveito de todo e qualquer pacote isomórfico em Vanilla Javascript já feito em toda história.
Todo o sua aplicação fala a mesma língua.A estrutura horizontal, ao contrário de uma hierárquica, torna muito mais fácil mover os recursos.
Flexibilidade acima de burocracia.Métodos de ciclo de vida são funções nomeadas de forma especial que você pode declarar na classe.
-Cada método de ciclo de vida roda em uma fila de ordem específica, garantindo que todos os componentes do ciclo atual sejam preparados antes do primeiro ser iniciado.
-Esse método é bloqueante e roda antes da primeira renderização do componente.
-Você pode usar essa função para definir o estado que o usuário verá antes do carregamento.
-Se o usuário estiver entrando através dessa rota, prepare irá rodar no servidor antes do Nullstack renderizar sua aplicação no lado do servidor.
Se o usuário estiver navegando por outra rota, esse método rodará no cliente.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- prepare() {
- this.date = new Date();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Esse método pode ser assíncrono, e roda assim que o componente for preparado e renderizado pela primeira vez.
-Você pode usá-lo para invocar outra função do servidor e carregar os dados para apresentar a página.
-Se o usuário estiver entrando através dessa rota, initiate rodará no servidor.
Nullstack irá esperar até que a promise seja resolvida e então finalmente irá gerar o HTML que será servido.
-Se o usuário estiver navegando por outra rota, esse método rodará no cliente.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async initiate() {
- this.task = await getTaskByDay({
- day: this.date
- });
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Aprenda mais sobre funções do servidor.
-
Esse método é assíncrono e rodará apenas no cliente.
-Ele sempre rodará independente do ambiente que iniciou o componente.
-Esse é um bom lugar para acionar dependências que manipulam o DOM ou que podem rodar apenas no lado do cliente.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async hydrate() {
- this.timer = setInterval(() => {
- console.log(this.date);
- }, 1000);
- }
-
- // ...
-
-}
-
-export default Component;
-
-Esse método é assíncrono e rodará apenas no cliente.
-Ele roda em todos os componentes sempre que o estado da aplicação mudar.
---🔥 Tome cuidado para não causar loops infinitos quando mutacionar o estado dentro de
-update.
Ele irá rodar logo antes da renderização, mas não irá bloquear a fila.
-A função update não rodará até que a aplicação seja renderizada após initiate.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async update() {
- const today = new Date();
- if(today.getDay() != this.date.getDay()) {
- this.date = today;
- await this.initiate();
- }
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Métodos de ciclo de vida não têm efeitos colaterais, você pode chamá-los manualmentes sem causar problemas.
-
Esse método é assíncrono e rodará apenas no cliente.
-Ele irá rodar após o componente deixar o DOM.
-Esse é o lugar para limpar qualquer coisa que você definiu no método hydrate.
Essa instância será levada pelo garbage collector após a resolução da Promise.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async terminate() {
- clearInterval(this.timer);
- }
-
- // ...
-
-}
-
-export default Component;
-
-⚔ Aprenda sobre funções do servidor.
-Métodos de ciclo de vida são funções nomeadas de forma especial que você pode declarar na classe.
-Cada método de ciclo de vida roda em uma fila de ordem específica, garantindo que todos os componentes do ciclo atual sejam preparados antes do primeiro ser iniciado.
-Esse método é bloqueante e roda antes da primeira renderização do componente.
-Você pode usar essa função para definir o estado que o usuário verá antes do carregamento.
-Se o usuário estiver entrando através dessa rota, prepare irá rodar no servidor antes do Nullstack renderizar sua aplicação no lado do servidor.
Se o usuário estiver navegando por outra rota, esse método rodará no cliente.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- prepare() {
- this.date = new Date();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Esse método pode ser assíncrono, e roda assim que o componente for preparado e renderizado pela primeira vez.
-Você pode usá-lo para invocar outra função do servidor e carregar os dados para apresentar a página.
-Se o usuário estiver entrando através dessa rota, initiate rodará no servidor.
Nullstack irá esperar até que a promise seja resolvida e então finalmente irá gerar o HTML que será servido.
-Se o usuário estiver navegando por outra rota, esse método rodará no cliente.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async initiate() {
- this.task = await getTaskByDay({
- day: this.date
- });
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Aprenda mais sobre funções do servidor.
-
Esse método é assíncrono e rodará apenas no cliente.
-Ele sempre rodará independente do ambiente que iniciou o componente.
-Esse é um bom lugar para acionar dependências que manipulam o DOM ou que podem rodar apenas no lado do cliente.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async hydrate() {
- this.timer = setInterval(() => {
- console.log(this.date);
- }, 1000);
- }
-
- // ...
-
-}
-
-export default Component;
-
-Esse método é assíncrono e rodará apenas no cliente.
-Ele roda em todos os componentes sempre que o estado da aplicação mudar.
---🔥 Tome cuidado para não causar loops infinitos quando mutacionar o estado dentro de
-update.
Ele irá rodar logo antes da renderização, mas não irá bloquear a fila.
-A função update não rodará até que a aplicação seja renderizada após initiate.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async update() {
- const today = new Date();
- if(today.getDay() != this.date.getDay()) {
- this.date = today;
- await this.initiate();
- }
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Métodos de ciclo de vida não têm efeitos colaterais, você pode chamá-los manualmentes sem causar problemas.
-
Esse método é assíncrono e rodará apenas no cliente.
-Ele irá rodar após o componente deixar o DOM.
-Esse é o lugar para limpar qualquer coisa que você definiu no método hydrate.
Essa instância será levada pelo garbage collector após a resolução da Promise.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async terminate() {
- clearInterval(this.timer);
- }
-
- // ...
-
-}
-
-export default Component;
-
-⚔ Aprenda sobre funções do servidor.
-Métodos de ciclo de vida são funções nomeadas de forma especial que você pode declarar na classe.
\nCada método de ciclo de vida roda em uma fila de ordem específica, garantindo que todos os componentes do ciclo atual sejam preparados antes do primeiro ser iniciado.
\nEsse método é bloqueante e roda antes da primeira renderização do componente.
\nVocê pode usar essa função para definir o estado que o usuário verá antes do carregamento.
\nSe o usuário estiver entrando através dessa rota, prepare irá rodar no servidor antes do Nullstack renderizar sua aplicação no lado do servidor.
Se o usuário estiver navegando por outra rota, esse método rodará no cliente.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n prepare() {\n this.date = new Date();\n }\n\n // ...\n\n}\n\nexport default Component;\n\nEsse método pode ser assíncrono, e roda assim que o componente for preparado e renderizado pela primeira vez.
\nVocê pode usá-lo para invocar outra função do servidor e carregar os dados para apresentar a página.
\nSe o usuário estiver entrando através dessa rota, initiate rodará no servidor.
Nullstack irá esperar até que a promise seja resolvida e então finalmente irá gerar o HTML que será servido.
\nSe o usuário estiver navegando por outra rota, esse método rodará no cliente.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async initiate() {\n this.task = await getTaskByDay({\n day: this.date\n });\n }\n\n // ...\n\n}\n\nexport default Component;\n\n\n\n✨ Aprenda mais sobre funções do servidor.
\n
Esse método é assíncrono e rodará apenas no cliente.
\nEle sempre rodará independente do ambiente que iniciou o componente.
\nEsse é um bom lugar para acionar dependências que manipulam o DOM ou que podem rodar apenas no lado do cliente.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async hydrate() {\n this.timer = setInterval(() => {\n console.log(this.date);\n }, 1000);\n }\n\n // ...\n\n}\n\nexport default Component;\n\nEsse método é assíncrono e rodará apenas no cliente.
\nEle roda em todos os componentes sempre que o estado da aplicação mudar.
\n\n\n🔥 Tome cuidado para não causar loops infinitos quando mutacionar o estado dentro de
\nupdate.
Ele irá rodar logo antes da renderização, mas não irá bloquear a fila.
\nA função update não rodará até que a aplicação seja renderizada após initiate.
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async update() {\n const today = new Date();\n if(today.getDay() != this.date.getDay()) {\n this.date = today;\n await this.initiate();\n }\n }\n\n // ...\n\n}\n\nexport default Component;\n\n\n\n✨ Métodos de ciclo de vida não têm efeitos colaterais, você pode chamá-los manualmentes sem causar problemas.
\n
Esse método é assíncrono e rodará apenas no cliente.
\nEle irá rodar após o componente deixar o DOM.
\nEsse é o lugar para limpar qualquer coisa que você definiu no método hydrate.
Essa instância será levada pelo garbage collector após a resolução da Promise.
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async terminate() {\n clearInterval(this.timer);\n }\n\n // ...\n\n}\n\nexport default Component;\n\n⚔ Aprenda sobre funções do servidor.
\n","description":"Métodos de ciclo de vida são funções nomeadas de forma especial que você pode declarar na classe"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Ciclo de Vida Full-Stack - Nullstack","description":"Métodos de ciclo de vida são funções nomeadas de forma especial que você pode declarar na classe"}} \ No newline at end of file diff --git a/docs/pt-br/comecando.html b/docs/pt-br/comecando.html deleted file mode 100644 index 9d971fc4..00000000 --- a/docs/pt-br/comecando.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - ---📌 Você pode assistir um tutorial no nosso Canal do Youtube.
-
Crie aplicações javascript full-stack em segundos usando npx para gerar os arquivos do seu projeto usando o template mais recente.
--🔥 A versão mínima necessária do node.js para o modo de desenvovimento é 12.12.0.
-
--⚠ Se o diretório em que você está contém espaços, você usa Windows e o
-npxder erros, leia sobre o bug conhecido do npx.
Troque project-name com o nome do seu projeto e rode o comanto abaixo para começar um projeto:
npx create-nullstack-app project-name
-
-Troque o diretório para a pasta gerada:
-cd project-name
-
-Instale as dependências:
-npm install
-
-Inicie a aplicação em modo de desenvolvimento:
-npm start
-
-As seguintes pastas e arquivos serão gerados:
-Este é o ponto de entrada do Webpack.
-Normalmente, você não precisará mexer neste arquivo, mas é um lugar conveniente para importar dependências globais como frameworks CSS.
-Esta pasta contêm o código fonte da sua aplicação.
-Este é o arquivo principal da sua aplicação.
---✨ Saiba mais sobre a extensão de arquivo njs.
-
A função start será automaticamente chamada uma vez que você rode npm start, use a para preencher o contexto do seu servidor com coisas como banco de dados, configurações, e segredos.
--✨ Saiba mais sobre a inicialização da aplicação.
-
Este é um arquivo vazio só para demonstrar que você pode usar SCSS com Nullstack.
-É uma boa prática importar um arquivo de estilo em um componente com o mesmo nome.
---✨ Saiba mais sobre estilos.
-
Todo arquivo aqui ficará disponível para qualquer um na raíz do domínio.
-Por padrão create-nullstack-app gera os ícones necessários para o seu manifest.json e imagens para meta tags OG.
--✨ Saiba mais sobre o manifest.json.
-
Tenha certeza de trocar estas imagens pela identidade do seu projeto.
-Este é o resultado compilado da sua aplicação em modo de desenvolvimento.
---🔥 Não toque nesta pasta
-
Este é o resultado compilado da sua aplicação em modo de produção.
---🔥 Não toque nesta pasta
-
--✨ Saiba mais sobre como fazer deploy de aplicação Nullstack.
-
Avisado em issues do npx como #100, #110 e #143, ele tem um erro ao tentar resolver o caminho para sua pasta de cache quando este contém espaços.
Se isso ocorrer com você, nossas recomendações são:
-Usando baixado como normalmente faria com npm:
npm i -g create-nullstack-app
-create-nullstack-app project-name
-ou, mudar o diretório da pasta de cache, como dito aqui e aqui:
-PrimeiroNome pelo usado no seu caminho e rode:npm config set cache "C:\Users\PrimeiroNome~1\AppData\Roaming\npm-cache" --global
-
-npm config set cache C:\tmp\nodejs\npm-cache --global
-⚔ Crie seu primeiro componente renderizável.
---📌 Você pode assistir um tutorial no nosso Canal do Youtube.
-
Crie aplicações javascript full-stack em segundos usando npx para gerar os arquivos do seu projeto usando o template mais recente.
--🔥 A versão mínima necessária do node.js para o modo de desenvovimento é 12.12.0.
-
--⚠ Se o diretório em que você está contém espaços, você usa Windows e o
-npxder erros, leia sobre o bug conhecido do npx.
Troque project-name com o nome do seu projeto e rode o comanto abaixo para começar um projeto:
npx create-nullstack-app project-name
-
-Troque o diretório para a pasta gerada:
-cd project-name
-
-Instale as dependências:
-npm install
-
-Inicie a aplicação em modo de desenvolvimento:
-npm start
-
-As seguintes pastas e arquivos serão gerados:
-Este é o ponto de entrada do Webpack.
-Normalmente, você não precisará mexer neste arquivo, mas é um lugar conveniente para importar dependências globais como frameworks CSS.
-Esta pasta contêm o código fonte da sua aplicação.
-Este é o arquivo principal da sua aplicação.
---✨ Saiba mais sobre a extensão de arquivo njs.
-
A função start será automaticamente chamada uma vez que você rode npm start, use a para preencher o contexto do seu servidor com coisas como banco de dados, configurações, e segredos.
--✨ Saiba mais sobre a inicialização da aplicação.
-
Este é um arquivo vazio só para demonstrar que você pode usar SCSS com Nullstack.
-É uma boa prática importar um arquivo de estilo em um componente com o mesmo nome.
---✨ Saiba mais sobre estilos.
-
Todo arquivo aqui ficará disponível para qualquer um na raíz do domínio.
-Por padrão create-nullstack-app gera os ícones necessários para o seu manifest.json e imagens para meta tags OG.
--✨ Saiba mais sobre o manifest.json.
-
Tenha certeza de trocar estas imagens pela identidade do seu projeto.
-Este é o resultado compilado da sua aplicação em modo de desenvolvimento.
---🔥 Não toque nesta pasta
-
Este é o resultado compilado da sua aplicação em modo de produção.
---🔥 Não toque nesta pasta
-
--✨ Saiba mais sobre como fazer deploy de aplicação Nullstack.
-
Avisado em issues do npx como #100, #110 e #143, ele tem um erro ao tentar resolver o caminho para sua pasta de cache quando este contém espaços.
Se isso ocorrer com você, nossas recomendações são:
-Usando baixado como normalmente faria com npm:
npm i -g create-nullstack-app
-create-nullstack-app project-name
-ou, mudar o diretório da pasta de cache, como dito aqui e aqui:
-PrimeiroNome pelo usado no seu caminho e rode:npm config set cache "C:\Users\PrimeiroNome~1\AppData\Roaming\npm-cache" --global
-
-npm config set cache C:\tmp\nodejs\npm-cache --global
-⚔ Crie seu primeiro componente renderizável.
-\n\n📌 Você pode assistir um tutorial no nosso Canal do Youtube.
\n
Crie aplicações javascript full-stack em segundos usando npx para gerar os arquivos do seu projeto usando o template mais recente.
\n\n🔥 A versão mínima necessária do node.js para o modo de desenvovimento é 12.12.0.
\n
\n\n⚠ Se o diretório em que você está contém espaços, você usa Windows e o
\nnpxder erros, leia sobre o bug conhecido do npx.
Troque project-name com o nome do seu projeto e rode o comanto abaixo para começar um projeto:
npx create-nullstack-app project-name\n\nTroque o diretório para a pasta gerada:
\ncd project-name\n\nInstale as dependências:
\nnpm install\n\nInicie a aplicação em modo de desenvolvimento:
\nnpm start\n\nAs seguintes pastas e arquivos serão gerados:
\nEste é o ponto de entrada do Webpack.
\nNormalmente, você não precisará mexer neste arquivo, mas é um lugar conveniente para importar dependências globais como frameworks CSS.
\nEsta pasta contêm o código fonte da sua aplicação.
\nEste é o arquivo principal da sua aplicação.
\n\n\n✨ Saiba mais sobre a extensão de arquivo njs.
\n
A função start será automaticamente chamada uma vez que você rode npm start, use a para preencher o contexto do seu servidor com coisas como banco de dados, configurações, e segredos.
\n\n✨ Saiba mais sobre a inicialização da aplicação.
\n
Este é um arquivo vazio só para demonstrar que você pode usar SCSS com Nullstack.
\nÉ uma boa prática importar um arquivo de estilo em um componente com o mesmo nome.
\n\n\n✨ Saiba mais sobre estilos.
\n
Todo arquivo aqui ficará disponível para qualquer um na raíz do domínio.
\nPor padrão create-nullstack-app gera os ícones necessários para o seu manifest.json e imagens para meta tags OG.
\n\n✨ Saiba mais sobre o manifest.json.
\n
Tenha certeza de trocar estas imagens pela identidade do seu projeto.
\nEste é o resultado compilado da sua aplicação em modo de desenvolvimento.
\n\n\n🔥 Não toque nesta pasta
\n
Este é o resultado compilado da sua aplicação em modo de produção.
\n\n\n🔥 Não toque nesta pasta
\n
\n\n✨ Saiba mais sobre como fazer deploy de aplicação Nullstack.
\n
Avisado em issues do npx como #100, #110 e #143, ele tem um erro ao tentar resolver o caminho para sua pasta de cache quando este contém espaços.
Se isso ocorrer com você, nossas recomendações são:
\nUsando baixado como normalmente faria com npm:
npm i -g create-nullstack-app\ncreate-nullstack-app project-name\nou, mudar o diretório da pasta de cache, como dito aqui e aqui:
\nPrimeiroNome pelo usado no seu caminho e rode:npm config set cache \"C:\\Users\\PrimeiroNome~1\\AppData\\Roaming\\npm-cache\" --global\n\nnpm config set cache C:\\tmp\\nodejs\\npm-cache --global\n⚔ Crie seu primeiro componente renderizável.
\n","description":"Crie aplicações full-stack em javascript em meros segundos"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Começando - Nullstack","description":"Crie aplicações full-stack em javascript em meros segundos"}} \ No newline at end of file diff --git a/docs/pt-br/como-fazer-deploy-de-aplicacao-nullstack.html b/docs/pt-br/como-fazer-deploy-de-aplicacao-nullstack.html deleted file mode 100644 index 8026ef0a..00000000 --- a/docs/pt-br/como-fazer-deploy-de-aplicacao-nullstack.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - -Com o Nullstack é fácil ter sua aplicação instalada e funcionando no modo de produção
---🐱💻 stonks
-
Nullstack compila seu código e todas as suas dependências usando Webpack.
-A saída da compilação é movida para a pasta .production e é a única pasta além de public que precisa ser movida para a máquina host.
-Se você tiver project.cdn definido, deverá mover a pasta public para o cdn real.
--💡 É importante que a pasta .production esteja presente para a detecção do ambiente
-
A máquina host deve ter pelo menos a versão 8.10.0 do node instalada.
-Você não precisa executar "npm install" na máquina host.
-- --
Para iniciar o servidor, basta executar:
-node .production/server.js
-
---✨ Recomenda-se o uso de um gerenciador de processos como PM2
-
Depois de gerar um site estático, tudo o que você precisa fazer é mover a pasta de saída para qualquer máquina host capaz de servir HTML.
---🎉 Parabéns. Você concluiu os conceitos avançados!
-
⚔ Aprenda como usar MongoDB com Nullstack.
-Com o Nullstack é fácil ter sua aplicação instalada e funcionando no modo de produção
---🐱💻 stonks
-
Nullstack compila seu código e todas as suas dependências usando Webpack.
-A saída da compilação é movida para a pasta .production e é a única pasta além de public que precisa ser movida para a máquina host.
-Se você tiver project.cdn definido, deverá mover a pasta public para o cdn real.
--💡 É importante que a pasta .production esteja presente para a detecção do ambiente
-
A máquina host deve ter pelo menos a versão 8.10.0 do node instalada.
-Você não precisa executar "npm install" na máquina host.
-- --
Para iniciar o servidor, basta executar:
-node .production/server.js
-
---✨ Recomenda-se o uso de um gerenciador de processos como PM2
-
Depois de gerar um site estático, tudo o que você precisa fazer é mover a pasta de saída para qualquer máquina host capaz de servir HTML.
---🎉 Parabéns. Você concluiu os conceitos avançados!
-
⚔ Aprenda como usar MongoDB com Nullstack.
-Com o Nullstack é fácil ter sua aplicação instalada e funcionando no modo de produção
\n\n\n🐱💻 stonks
\n
Nullstack compila seu código e todas as suas dependências usando Webpack.
\nA saída da compilação é movida para a pasta .production e é a única pasta além de public que precisa ser movida para a máquina host.
\nSe você tiver project.cdn definido, deverá mover a pasta public para o cdn real.
\n\n💡 É importante que a pasta .production esteja presente para a detecção do ambiente
\n
A máquina host deve ter pelo menos a versão 8.10.0 do node instalada.
\nVocê não precisa executar "npm install" na máquina host.
\n\n\n\n
Para iniciar o servidor, basta executar:
\nnode .production/server.js\n\n\n\n✨ Recomenda-se o uso de um gerenciador de processos como PM2
\n
Depois de gerar um site estático, tudo o que você precisa fazer é mover a pasta de saída para qualquer máquina host capaz de servir HTML.
\n\n\n🎉 Parabéns. Você concluiu os conceitos avançados!
\n
⚔ Aprenda como usar MongoDB com Nullstack.
\n","description":"Com o Nullstack é fácil ter sua aplicação instalada e funcionando no modo de produção"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Como fazer Deploy - Nullstack","description":"Com o Nullstack é fácil ter sua aplicação instalada e funcionando no modo de produção"}} \ No newline at end of file diff --git a/docs/pt-br/como-usar-facebook-pixel-no-nullstack.html b/docs/pt-br/como-usar-facebook-pixel-no-nullstack.html deleted file mode 100644 index 6ce18d1d..00000000 --- a/docs/pt-br/como-usar-facebook-pixel-no-nullstack.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - -De acordo com developers.facebook.com:
-"O Facebook Pixel é um trecho de código JavaScript que permite rastrear a atividade do visitante em seu site."
-Você pode aproveitar as vantagens do contexto e dos eventos personalizados para criar um componente que envia eventos Pixel dinamicamente.
-O Facebook Pixel só pode ser chamado depois de hydrate para garantir que está sendo executado no cliente.
import Nullstack from 'nullstack';
-
-class FacebookPixel extends Nullstack {
-
- async hydrate({page, id}) {
- ! function(f, b, e, v, n, t, s) {
- if (f.fbq) return;
- n = f.fbq = function() {
- n.callMethod ?
- n.callMethod.apply(n, arguments) : n.queue.push(arguments)
- };
- if (!f._fbq) f._fbq = n;
- n.push = n;
- n.loaded = !0;
- n.version = '2.0';
- n.queue = [];
- t = b.createElement(e);
- t.async = !0;
- t.src = v;
- s = b.getElementsByTagName(e)[0];
- s.parentNode.insertBefore(t, s)
- }(window, document, 'script',
- 'https://connect.facebook.net/en_US/fbevents.js');
- fbq('init', id);
- fbq('track', 'PageView');
- window.addEventListener(page.event, () => {
- fbq('init', id);
- fbq('track', 'PageView');
- })
- }
-}
-
-export default FacebookPixel;
-
-import Nullstack from 'nullstack';
-import FacebookPixel from './FacebookPixel';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <FacebookPixel id="SUBSTITUA_COM_SEU_ID_DO_FACEBOOK_PIXEL" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-Alternativamente, você pode instalar nullstack-facebook-pixel como uma dependência:
-npm install nullstack-facebook-pixel
-
-import Nullstack from 'nullstack';
-import FacebookPixel from 'nullstack-facebook-pixel';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <FacebookPixel id="SUBSTITUA_COM_SEU_ID_DO_FACEBOOK_PIXEL" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
---🎉 Parabéns. Você concluiu a documentação!
-
⚔ Se você deseja ver mais exemplos aqui, abra uma issue no github.
-De acordo com developers.facebook.com:
-"O Facebook Pixel é um trecho de código JavaScript que permite rastrear a atividade do visitante em seu site."
-Você pode aproveitar as vantagens do contexto e dos eventos personalizados para criar um componente que envia eventos Pixel dinamicamente.
-O Facebook Pixel só pode ser chamado depois de hydrate para garantir que está sendo executado no cliente.
import Nullstack from 'nullstack';
-
-class FacebookPixel extends Nullstack {
-
- async hydrate({page, id}) {
- ! function(f, b, e, v, n, t, s) {
- if (f.fbq) return;
- n = f.fbq = function() {
- n.callMethod ?
- n.callMethod.apply(n, arguments) : n.queue.push(arguments)
- };
- if (!f._fbq) f._fbq = n;
- n.push = n;
- n.loaded = !0;
- n.version = '2.0';
- n.queue = [];
- t = b.createElement(e);
- t.async = !0;
- t.src = v;
- s = b.getElementsByTagName(e)[0];
- s.parentNode.insertBefore(t, s)
- }(window, document, 'script',
- 'https://connect.facebook.net/en_US/fbevents.js');
- fbq('init', id);
- fbq('track', 'PageView');
- window.addEventListener(page.event, () => {
- fbq('init', id);
- fbq('track', 'PageView');
- })
- }
-}
-
-export default FacebookPixel;
-
-import Nullstack from 'nullstack';
-import FacebookPixel from './FacebookPixel';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <FacebookPixel id="SUBSTITUA_COM_SEU_ID_DO_FACEBOOK_PIXEL" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-Alternativamente, você pode instalar nullstack-facebook-pixel como uma dependência:
-npm install nullstack-facebook-pixel
-
-import Nullstack from 'nullstack';
-import FacebookPixel from 'nullstack-facebook-pixel';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <FacebookPixel id="SUBSTITUA_COM_SEU_ID_DO_FACEBOOK_PIXEL" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
---🎉 Parabéns. Você concluiu a documentação!
-
⚔ Se você deseja ver mais exemplos aqui, abra uma issue no github.
-De acordo com developers.facebook.com:
\n"O Facebook Pixel é um trecho de código JavaScript que permite rastrear a atividade do visitante em seu site."
\nVocê pode aproveitar as vantagens do contexto e dos eventos personalizados para criar um componente que envia eventos Pixel dinamicamente.
\nO Facebook Pixel só pode ser chamado depois de hydrate para garantir que está sendo executado no cliente.
import Nullstack from 'nullstack';\n\nclass FacebookPixel extends Nullstack {\n\n async hydrate({page, id}) {\n ! function(f, b, e, v, n, t, s) {\n if (f.fbq) return;\n n = f.fbq = function() {\n n.callMethod ?\n n.callMethod.apply(n, arguments) : n.queue.push(arguments)\n };\n if (!f._fbq) f._fbq = n;\n n.push = n;\n n.loaded = !0;\n n.version = '2.0';\n n.queue = [];\n t = b.createElement(e);\n t.async = !0;\n t.src = v;\n s = b.getElementsByTagName(e)[0];\n s.parentNode.insertBefore(t, s)\n }(window, document, 'script',\n 'https://connect.facebook.net/en_US/fbevents.js');\n fbq('init', id);\n fbq('track', 'PageView');\n window.addEventListener(page.event, () => {\n fbq('init', id);\n fbq('track', 'PageView');\n })\n }\n}\n\nexport default FacebookPixel;\n\nimport Nullstack from 'nullstack';\nimport FacebookPixel from './FacebookPixel';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <FacebookPixel id=\"SUBSTITUA_COM_SEU_ID_DO_FACEBOOK_PIXEL\" />\n </main>\n )\n }\n\n\n}\n\nexport default Application;\n\nAlternativamente, você pode instalar nullstack-facebook-pixel como uma dependência:
\nnpm install nullstack-facebook-pixel\n\nimport Nullstack from 'nullstack';\nimport FacebookPixel from 'nullstack-facebook-pixel';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <FacebookPixel id=\"SUBSTITUA_COM_SEU_ID_DO_FACEBOOK_PIXEL\" />\n </main>\n )\n }\n\n\n}\n\nexport default Application;\n\n\n\n🎉 Parabéns. Você concluiu a documentação!
\n
⚔ Se você deseja ver mais exemplos aqui, abra uma issue no github.
\n","description":"Aproveite as vantagens do [contexto](/pt-br/contexto) e [eventos personalizados](/pt-br/contexto-page) para criar um componente que envia eventos Pixel dinamicamente."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Facebook Pixel - Nullstack","description":"Aproveite as vantagens do [contexto](/pt-br/contexto) e [eventos personalizados](/pt-br/contexto-page) para criar um componente que envia eventos Pixel dinamicamente."}} \ No newline at end of file diff --git a/docs/pt-br/como-usar-google-analytics-no-nullstack.html b/docs/pt-br/como-usar-google-analytics-no-nullstack.html deleted file mode 100644 index 1c9f26d4..00000000 --- a/docs/pt-br/como-usar-google-analytics-no-nullstack.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - -De acordo com analytics.google.com:
-"O Google Analytics permite que você avalie o ROI de publicidade, bem como rastreie o Flash, vídeo e mídias sociais em sites e aplicativos."
-Você pode aproveitar as vantagens do contexto e dos eventos personalizados para criar um componente que envia eventos GTAG dinamicamente.
-O GTAG só pode ser chamado depois de hydrate para garantir que está sendo executado no cliente.
import Nullstack from 'nullstack';
-
-class GoogleAnalytics extends Nullstack {
-
- hydrate({router, page, id}) {
- window.dataLayer = window.dataLayer || [];
- function gtag(){
- dataLayer.push(arguments);
- }
- gtag('js', new Date());
- gtag('config', id, {
- page_title: page.title,
- page_path: router.url
- });
- window.addEventListener(page.event, () => {
- gtag('event', 'page_view', {
- page_title: page.title,
- page_path: router.url
- })
- })
- }
-
- render({id}) {
- return (
- <script
- async
- src={`https://www.googletagmanager.com/gtag/js?id=${id}`}
- />
- )
- }
-
-}
-
-export default GoogleAnalytics;
-
-import Nullstack from 'nullstack';
-import GoogleAnalytics from './GoogleAnalytics';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <GoogleAnalytics id="SUBSTITUA_COM_SEU_ID_DO_GOOGLE_ANALYTICS" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-Alternativamente, você pode instalar o nullstack-google-analytics como uma dependência:
-npm install nullstack-google-analytics
-
-import Nullstack from 'nullstack';
-import GoogleAnalytics from 'nullstack-google-analytics';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <GoogleAnalytics id="SUBSTITUA_COM_SEU_ID_DO_GOOGLE_ANALYTICS" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-⚔ Aprenda como usar o Facebook Pixel com o Nullstack.
-De acordo com analytics.google.com:
-"O Google Analytics permite que você avalie o ROI de publicidade, bem como rastreie o Flash, vídeo e mídias sociais em sites e aplicativos."
-Você pode aproveitar as vantagens do contexto e dos eventos personalizados para criar um componente que envia eventos GTAG dinamicamente.
-O GTAG só pode ser chamado depois de hydrate para garantir que está sendo executado no cliente.
import Nullstack from 'nullstack';
-
-class GoogleAnalytics extends Nullstack {
-
- hydrate({router, page, id}) {
- window.dataLayer = window.dataLayer || [];
- function gtag(){
- dataLayer.push(arguments);
- }
- gtag('js', new Date());
- gtag('config', id, {
- page_title: page.title,
- page_path: router.url
- });
- window.addEventListener(page.event, () => {
- gtag('event', 'page_view', {
- page_title: page.title,
- page_path: router.url
- })
- })
- }
-
- render({id}) {
- return (
- <script
- async
- src={`https://www.googletagmanager.com/gtag/js?id=${id}`}
- />
- )
- }
-
-}
-
-export default GoogleAnalytics;
-
-import Nullstack from 'nullstack';
-import GoogleAnalytics from './GoogleAnalytics';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <GoogleAnalytics id="SUBSTITUA_COM_SEU_ID_DO_GOOGLE_ANALYTICS" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-Alternativamente, você pode instalar o nullstack-google-analytics como uma dependência:
-npm install nullstack-google-analytics
-
-import Nullstack from 'nullstack';
-import GoogleAnalytics from 'nullstack-google-analytics';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <GoogleAnalytics id="SUBSTITUA_COM_SEU_ID_DO_GOOGLE_ANALYTICS" />
- </main>
- )
- }
-
-
-}
-
-export default Application;
-
-⚔ Aprenda como usar o Facebook Pixel com o Nullstack.
-De acordo com analytics.google.com:
\n"O Google Analytics permite que você avalie o ROI de publicidade, bem como rastreie o Flash, vídeo e mídias sociais em sites e aplicativos."
\nVocê pode aproveitar as vantagens do contexto e dos eventos personalizados para criar um componente que envia eventos GTAG dinamicamente.
\nO GTAG só pode ser chamado depois de hydrate para garantir que está sendo executado no cliente.
import Nullstack from 'nullstack';\n\nclass GoogleAnalytics extends Nullstack {\n\n hydrate({router, page, id}) {\n window.dataLayer = window.dataLayer || [];\n function gtag(){\n dataLayer.push(arguments);\n }\n gtag('js', new Date());\n gtag('config', id, {\n page_title: page.title,\n page_path: router.url\n });\n window.addEventListener(page.event, () => {\n gtag('event', 'page_view', {\n page_title: page.title,\n page_path: router.url\n })\n })\n }\n \n render({id}) {\n return (\n <script \n async\n src={`https://www.googletagmanager.com/gtag/js?id=${id}`}\n />\n )\n }\n\n}\n\nexport default GoogleAnalytics;\n\nimport Nullstack from 'nullstack';\nimport GoogleAnalytics from './GoogleAnalytics';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <GoogleAnalytics id=\"SUBSTITUA_COM_SEU_ID_DO_GOOGLE_ANALYTICS\" />\n </main>\n )\n }\n\n\n}\n\nexport default Application;\n\nAlternativamente, você pode instalar o nullstack-google-analytics como uma dependência:
\nnpm install nullstack-google-analytics\n\nimport Nullstack from 'nullstack';\nimport GoogleAnalytics from 'nullstack-google-analytics';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <GoogleAnalytics id=\"SUBSTITUA_COM_SEU_ID_DO_GOOGLE_ANALYTICS\" />\n </main>\n )\n }\n\n\n}\n\nexport default Application;\n\n⚔ Aprenda como usar o Facebook Pixel com o Nullstack.
\n","description":"Aproveite as vantagens do contexto e dos eventos personalizados para criar um componente que envia eventos GTAG dinamicamente."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Google Analytics - Nullstack","description":"Aproveite as vantagens do contexto e dos eventos personalizados para criar um componente que envia eventos GTAG dinamicamente."}} \ No newline at end of file diff --git a/docs/pt-br/como-usar-mongodb-com-nullstack.html b/docs/pt-br/como-usar-mongodb-com-nullstack.html deleted file mode 100644 index 4fb3f74e..00000000 --- a/docs/pt-br/como-usar-mongodb-com-nullstack.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - -De acordo com mongodb.com:
-"O MongoDB é um banco de dados distribuído de propósito geral, baseado em documentos, criado para desenvolvedores de aplicativos modernos e para a era da nuvem."
-Você pode usar qualquer banco de dados com Nullstack, mas a integração javascript e flexibilidade do MongoDB parece especialmente boa com aplicativos Nullstack.
-Instale o driver MongoDB do npm:
-npm install mongodb
-
-Configure as credenciais do banco de dados usando secrets.
O último passo é simplesmente atribuir a conexão do banco de dados ao contexto do servidor.
-import Nullstack from 'nullstack';
-import {MongoClient} from 'mongodb';
-
-class Application extends Nullstack {
-
- static async start(context) {
- const {secrets} = context;
- secrets.development.databaseHost = 'mongodb://localhost:27017/dbname';
- secrets.databaseName = 'dbname';
- await this.startDatabase(context);
- }
-
- static async startDatabase(context) {
- const {secrets} = context;
- const databaseClient = new MongoClient(secrets.databaseHost);
- await databaseClient.connect();
- context.database = await databaseClient.db(secrets.databaseName);
- }
-
-}
-
-export default Application;
-
-O exemplo acima tornará a chave database disponível para todas as funções do servidor.
import Nullstack from 'nullstack';
-
-class BooksList extends Nullstack {
-
- books = [];
-
- static async getBooks({database}) {
- return await database.collection('books').find().toArray();
- }
-
- async initiate() {
- this.books = await this.getBooks();
- }
-
- // ...
-
-}
-
-export default BooksList;
-
-⚔ Aprenda como usar Google Analytics no Nullstack.
-De acordo com mongodb.com:
-"O MongoDB é um banco de dados distribuído de propósito geral, baseado em documentos, criado para desenvolvedores de aplicativos modernos e para a era da nuvem."
-Você pode usar qualquer banco de dados com Nullstack, mas a integração javascript e flexibilidade do MongoDB parece especialmente boa com aplicativos Nullstack.
-Instale o driver MongoDB do npm:
-npm install mongodb
-
-Configure as credenciais do banco de dados usando secrets.
O último passo é simplesmente atribuir a conexão do banco de dados ao contexto do servidor.
-import Nullstack from 'nullstack';
-import {MongoClient} from 'mongodb';
-
-class Application extends Nullstack {
-
- static async start(context) {
- const {secrets} = context;
- secrets.development.databaseHost = 'mongodb://localhost:27017/dbname';
- secrets.databaseName = 'dbname';
- await this.startDatabase(context);
- }
-
- static async startDatabase(context) {
- const {secrets} = context;
- const databaseClient = new MongoClient(secrets.databaseHost);
- await databaseClient.connect();
- context.database = await databaseClient.db(secrets.databaseName);
- }
-
-}
-
-export default Application;
-
-O exemplo acima tornará a chave database disponível para todas as funções do servidor.
import Nullstack from 'nullstack';
-
-class BooksList extends Nullstack {
-
- books = [];
-
- static async getBooks({database}) {
- return await database.collection('books').find().toArray();
- }
-
- async initiate() {
- this.books = await this.getBooks();
- }
-
- // ...
-
-}
-
-export default BooksList;
-
-⚔ Aprenda como usar Google Analytics no Nullstack.
-De acordo com mongodb.com:
\n"O MongoDB é um banco de dados distribuído de propósito geral, baseado em documentos, criado para desenvolvedores de aplicativos modernos e para a era da nuvem."
\nVocê pode usar qualquer banco de dados com Nullstack, mas a integração javascript e flexibilidade do MongoDB parece especialmente boa com aplicativos Nullstack.
\nInstale o driver MongoDB do npm:
\nnpm install mongodb\n\nConfigure as credenciais do banco de dados usando secrets.
O último passo é simplesmente atribuir a conexão do banco de dados ao contexto do servidor.
\nimport Nullstack from 'nullstack';\nimport {MongoClient} from 'mongodb';\n\nclass Application extends Nullstack {\n\n static async start(context) {\n const {secrets} = context;\n secrets.development.databaseHost = 'mongodb://localhost:27017/dbname';\n secrets.databaseName = 'dbname';\n await this.startDatabase(context);\n }\n\n static async startDatabase(context) {\n const {secrets} = context;\n const databaseClient = new MongoClient(secrets.databaseHost);\n await databaseClient.connect();\n context.database = await databaseClient.db(secrets.databaseName);\n }\n\n}\n\nexport default Application;\n\nO exemplo acima tornará a chave database disponível para todas as funções do servidor.
import Nullstack from 'nullstack';\n\nclass BooksList extends Nullstack {\n\n books = [];\n\n static async getBooks({database}) {\n return await database.collection('books').find().toArray();\n }\n\n async initiate() {\n this.books = await this.getBooks();\n }\n\n // ...\n\n}\n\nexport default BooksList;\n\n⚔ Aprenda como usar Google Analytics no Nullstack.
\n","description":"Você pode usar qualquer banco de dados com Nullstack, mas a integração javascript e flexibilidade do MongoDB parece especialmente boa com aplicativos Nullstack"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Como usar MongoDB - Nullstack","description":"Você pode usar qualquer banco de dados com Nullstack, mas a integração javascript e flexibilidade do MongoDB parece especialmente boa com aplicativos Nullstack"}} \ No newline at end of file diff --git a/docs/pt-br/componentes-com-estado.html b/docs/pt-br/componentes-com-estado.html deleted file mode 100644 index e4eada75..00000000 --- a/docs/pt-br/componentes-com-estado.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - -Um framework web full-stack produtivo não deve forçar você a pensar sobre detalhes de estrutura.
-Nullstack assume o controle de suas subclasses e gera um proxy para cada instância.
-Quando você invoca qualquer coisa em sua classe, você está na verdade dizendo ao Nullstack o que fazer com o ambiente nos bastidores.
-Isso permite que você use operações de javascript vanilla como atribuir a uma variável e ver o reflexo no dom.
-Você pode modificar variáveis de instância para atualizar o estado do seu aplicativo.
-As funções são vinculadas automaticamente ao proxy da instância e podem ser passadas como referência para eventos.
-Os eventos são declarados como atributos HTML normais.
-import Nullstack from "nullstack";
-
-class Counter extends Nullstack {
-
- count = 0;
-
- increment() {
- this.count++;
- }
-
- render() {
- return (
- <button onclick={this.increment}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
---💡 As atualizações são feitas em lotes, geralmente enquanto aguardam chamadas assíncronas, portanto, fazer várias atribuições não tem custos de desempenho!
-
Você pode criar atalho em eventos que são simples atribuições passando um objeto para o evento.
-Cada chave do objeto será atribuída à instância.
-import Nullstack from "nullstack";
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render() {
- return (
- <button onclick={{ count: this.count + 1 }}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
-Por padrão, os eventos referem-se a this quando você passa um objeto.
Você pode usar o atributo source para definir qual objeto receberá as atribuições.
import Nullstack from "nullstack";
-
-class Paginator extends Nullstack {
-
- render({ params }) {
- return (
- <button source={params} onclick={{ page: 1 }}>
- Primeira Página
- </button>
- )
- }
-
-}
-
-export default Paginator;
-
---✨ Aprenda mais sobre a chave
-paramsdo contexto.
--💡 Se você não declarar uma fonte para o evento, o Nullstack injetará
-source={this}no tempo de transpilação para pular completamente o processo de pesquisa em tempo de execução!
Os atributos do elemento-alvo do evento serão mesclados ao context da instância e podem ser desestruturados na assinatura da função.
import Nullstack from "nullstack";
-
-class Counter extends Nullstack {
-
- count = 0;
-
- increment({ delta }) {
- this.count += delta;
- }
-
- render() {
- return (
- <button onclick={this.increment} delta={2}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
---💡 Qualquer atributo com valor primitivo será adicionado ao DOM.
-
--✨ Considere usar atributos
-datapara tornar seu HTML válido.
O comportamento padrão do navegador é impedido por padrão.
-Você pode desativar isso declarando um atributo default para o elemento de evento.
Uma referência ao evento original é sempre mesclada com o contexto da função.
-import Nullstack from "nullstack";
-
-class Form extends Nullstack {
- submit({ event }) {
- event.preventDefault();
- }
-
- render() {
- return (
- <form onsubmit={this.submit} default>
- <button> Enviar </button>
- </form>
- )
- }
-}
-
-export default Form;
-
-⚔ Aprenda sobre o ciclo da vida full-stack.
-Um framework web full-stack produtivo não deve forçar você a pensar sobre detalhes de estrutura.
-Nullstack assume o controle de suas subclasses e gera um proxy para cada instância.
-Quando você invoca qualquer coisa em sua classe, você está na verdade dizendo ao Nullstack o que fazer com o ambiente nos bastidores.
-Isso permite que você use operações de javascript vanilla como atribuir a uma variável e ver o reflexo no dom.
-Você pode modificar variáveis de instância para atualizar o estado do seu aplicativo.
-As funções são vinculadas automaticamente ao proxy da instância e podem ser passadas como referência para eventos.
-Os eventos são declarados como atributos HTML normais.
-import Nullstack from "nullstack";
-
-class Counter extends Nullstack {
-
- count = 0;
-
- increment() {
- this.count++;
- }
-
- render() {
- return (
- <button onclick={this.increment}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
---💡 As atualizações são feitas em lotes, geralmente enquanto aguardam chamadas assíncronas, portanto, fazer várias atribuições não tem custos de desempenho!
-
Você pode criar atalho em eventos que são simples atribuições passando um objeto para o evento.
-Cada chave do objeto será atribuída à instância.
-import Nullstack from "nullstack";
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render() {
- return (
- <button onclick={{ count: this.count + 1 }}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
-Por padrão, os eventos referem-se a this quando você passa um objeto.
Você pode usar o atributo source para definir qual objeto receberá as atribuições.
import Nullstack from "nullstack";
-
-class Paginator extends Nullstack {
-
- render({ params }) {
- return (
- <button source={params} onclick={{ page: 1 }}>
- Primeira Página
- </button>
- )
- }
-
-}
-
-export default Paginator;
-
---✨ Aprenda mais sobre a chave
-paramsdo contexto.
--💡 Se você não declarar uma fonte para o evento, o Nullstack injetará
-source={this}no tempo de transpilação para pular completamente o processo de pesquisa em tempo de execução!
Os atributos do elemento-alvo do evento serão mesclados ao context da instância e podem ser desestruturados na assinatura da função.
import Nullstack from "nullstack";
-
-class Counter extends Nullstack {
-
- count = 0;
-
- increment({ delta }) {
- this.count += delta;
- }
-
- render() {
- return (
- <button onclick={this.increment} delta={2}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
---💡 Qualquer atributo com valor primitivo será adicionado ao DOM.
-
--✨ Considere usar atributos
-datapara tornar seu HTML válido.
O comportamento padrão do navegador é impedido por padrão.
-Você pode desativar isso declarando um atributo default para o elemento de evento.
Uma referência ao evento original é sempre mesclada com o contexto da função.
-import Nullstack from "nullstack";
-
-class Form extends Nullstack {
- submit({ event }) {
- event.preventDefault();
- }
-
- render() {
- return (
- <form onsubmit={this.submit} default>
- <button> Enviar </button>
- </form>
- )
- }
-}
-
-export default Form;
-
-⚔ Aprenda sobre o ciclo da vida full-stack.
-Um framework web full-stack produtivo não deve forçar você a pensar sobre detalhes de estrutura.
\nNullstack assume o controle de suas subclasses e gera um proxy para cada instância.
\nQuando você invoca qualquer coisa em sua classe, você está na verdade dizendo ao Nullstack o que fazer com o ambiente nos bastidores.
\nIsso permite que você use operações de javascript vanilla como atribuir a uma variável e ver o reflexo no dom.
\nVocê pode modificar variáveis de instância para atualizar o estado do seu aplicativo.
\nAs funções são vinculadas automaticamente ao proxy da instância e podem ser passadas como referência para eventos.
\nOs eventos são declarados como atributos HTML normais.
\nimport Nullstack from \"nullstack\";\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n increment() {\n this.count++;\n }\n\n render() {\n return (\n <button onclick={this.increment}>\n {this.count}\n </button>\n )\n }\n\n}\n\nexport default Counter;\n\n\n\n💡 As atualizações são feitas em lotes, geralmente enquanto aguardam chamadas assíncronas, portanto, fazer várias atribuições não tem custos de desempenho!
\n
Você pode criar atalho em eventos que são simples atribuições passando um objeto para o evento.
\nCada chave do objeto será atribuída à instância.
\nimport Nullstack from \"nullstack\";\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n render() {\n return (\n <button onclick={{ count: this.count + 1 }}>\n {this.count}\n </button>\n )\n }\n\n}\n\nexport default Counter;\n\nPor padrão, os eventos referem-se a this quando você passa um objeto.
Você pode usar o atributo source para definir qual objeto receberá as atribuições.
import Nullstack from \"nullstack\";\n\nclass Paginator extends Nullstack {\n\n render({ params }) {\n return (\n <button source={params} onclick={{ page: 1 }}>\n Primeira Página\n </button>\n )\n }\n\n}\n\nexport default Paginator;\n\n\n\n✨ Aprenda mais sobre a chave
\nparamsdo contexto.
\n\n💡 Se você não declarar uma fonte para o evento, o Nullstack injetará
\nsource={this}no tempo de transpilação para pular completamente o processo de pesquisa em tempo de execução!
Os atributos do elemento-alvo do evento serão mesclados ao context da instância e podem ser desestruturados na assinatura da função.
import Nullstack from \"nullstack\";\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n increment({ delta }) {\n this.count += delta;\n }\n\n render() {\n return (\n <button onclick={this.increment} delta={2}>\n {this.count}\n </button>\n )\n }\n\n}\n\nexport default Counter;\n\n\n\n💡 Qualquer atributo com valor primitivo será adicionado ao DOM.
\n
\n\n✨ Considere usar atributos
\ndatapara tornar seu HTML válido.
O comportamento padrão do navegador é impedido por padrão.
\nVocê pode desativar isso declarando um atributo default para o elemento de evento.
Uma referência ao evento original é sempre mesclada com o contexto da função.
\nimport Nullstack from \"nullstack\";\n\nclass Form extends Nullstack {\n submit({ event }) {\n event.preventDefault();\n }\n\n render() {\n return (\n <form onsubmit={this.submit} default>\n <button> Enviar </button>\n </form>\n )\n }\n}\n\nexport default Form;\n\n⚔ Aprenda sobre o ciclo da vida full-stack.
\n","description":"Um framework web full-stack produtivo não deve forçar você a pensar sobre detalhes de estrutura"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Componentes com estado - Nullstack","description":"Um framework web full-stack produtivo não deve forçar você a pensar sobre detalhes de estrutura"}} \ No newline at end of file diff --git a/docs/pt-br/componentes-renderizaveis.html b/docs/pt-br/componentes-renderizaveis.html deleted file mode 100644 index bee68210..00000000 --- a/docs/pt-br/componentes-renderizaveis.html +++ /dev/null @@ -1,309 +0,0 @@ - - - - - -O componente mais simples que você pode fazer é um componente renderizável.
-Componentes renderizáveis são muito semelhantes aos componentes da Web que fornecem a capacidade de criar novas tags HTML que atalham um grupo de outras tags HTML.
-Crie um arquivo em sua pasta src com o nome de seu componente e com a extensão .njs.
Neste exemplo, vai ser chamado helloworld.njs.
Tudo o que você precisa fazer é importar nullstack ou qualquer uma das suas subclasses e estender sua classe dele, definir um método de instância chamado render que retorna qualquer JSX e exporte o componente.
--✨ Instale a extensão oficial Nullstack para VSCode para gerar classes com snippets.
-
import Nullstack from "nullstack";
-
-class HelloWorld extends Nullstack {
-
- render() {
- return (
- <div> Olá Mundo </div>
- )
- }
-
-}
-
-export default HelloWorld;
-
-O código acima apenas declara o componente, você ainda tem que usá-lo.
-Importando o componente em seu aplicativo, temos a capacidade de usar uma nova tag em sua renderização.
-Esta tag será substituída pelo que você retornou no método render do componente.
import Nullstack from "nullstack";
-
-import "./Application.scss";
-
-import HelloWorld from "./HelloWorld";
-
-class Application extends Nullstack {
- // ...
-
- render({ page }) {
- return (
- <main>
- <h1> {page.title} </h1>
- <a href="https://nullstack.app/documentation" target="_blank">
- Read the documentation
- </a>
- <HelloWorld />
- </main>
- )
- }
-}
-
-export default Application;
-
-Nullstack JSX se desvia um pouco das especificações.
-Você pode usar os atributos HTML normais como class e for diretamente.
<label for="input" class="nao-me-rotule"> Eu sou um rótulo </label>
-
-Se você deseja pular a renderização do componente, você pode simplesmente retornar false da renderização.
import Nullstack from "nullstack";
-
-class Headless extends Nullstack {
-
- render() {
- return false;
- }
-
-}
-
-export default Headless;
-
-Isso alocará o espaço no DOM para quando você decidir renderizar a marcação lá.
-Isso também é útil para renderização condicional.
-Se tudo o que você deseja fazer é gerar um componente invisível, você pode ignorar a definição do método de renderização.
-Em vez de criar um novo componente apenas para organizar a divisão de código, você pode criar um componente interno.
-Componentes internos são quaisquer métodos cujo nome seja iniciado com render seguido por um caractere maiúsculo.
Componentes internos compartilham a mesma instância e escopo, pois o componente principal, portanto, são muito convenientes para evitar problemas como adereços de perfuração.
-Para invocar o componente interno, use uma tag JSX com o nome do método sem o prefixo render.
import Nullstack from "nullstack"
-
-class Post extends Nullstack {
-
- renderArticle() {
- return (
- <article> Conteúdo </article>
- )
- }
-
- renderAside() {
- return (
- <aside> Conteúdo Relacionado </aside>
- )
- }
-
- render() {
- return (
- <div>
- <Article />
- <Aside />
- </div>
- )
- }
-
-}
-
-export default HelloWorld;
-
---💡 Nullstack injetará uma referência constante à função no tempo de transpilação, a fim de ignorar completamente o processo de pesquisa de tempo de execução!
-
Os atributos podem ser atribuídos como booleanos.
-Quando o valor é false, o atributo não será renderizado.
Quando o valor for true, ele será processado como um atributo booleano sem um valor de string.
<button disabled={false}> Botão </button>
-
-Você pode abreviar atributos quando sabe que o valor será sempre verdadeiro.
-<button disabled> Botão </button>
-
---✨ Aprender mais sobre atributos.
-
Se você precisar decidir o nome da tag em tempo de execução, pode usar a tag do elemento e definir o atributo da tag condicionalmente.
-<element tag={!!link ? "a" : "span"} href={link || false}>
- algum texto arbitrário
-</element>
-
-Quando o atributo tag é omitido, Nullstack assumirá como padrão um div.
O SVG pode ser usado como se fosse qualquer tag HTML normal.
-Você pode manipular o SVG usando atributos e eventos normalmente.
-<svg height={this.size} viewBox="0 0 100 100">
- <circle cx="50" cy="50" r="40" onclick={this.grow} />
-</svg>
-
---✨ Aprender mais sobre eventos.
-
Seu componente pode ser invocado passando um bloco de conteúdo.
-<Header>
- <h1> Olá Mundo</h1>
-</Header>
-
-Isso não renderiza automaticamente o bloco, pois não saberia onde colocá-lo.
-Você pode desestruturar os filhos no método de renderização e colocá-los em sua marcação.
-import Nullstack from "nullstack";
-
-class Header extends Nullstack {
-
- render({ children }) {
- return (
- <div>{children}</div>
- )
- }
-
-}
-
-export default Header;
-
---✨ Isso é possível porque a chave
-childrenfaz parte do contexto da instância.
Você pode mapear listas sem declarar uma key.
As listas que podem mudar de comprimento devem ser agrupadas em um elemento pai apenas para elas.
-<ul>
- {list.map((item) => (
- <li>{item.name}</li>
- ))}
-</ul>
-
-Você pode emular uma lista de tamanho fixo, retornando false em vez de um elemento para reservar espaço no Dom.
{list.map((item) => (
- item.visible ? <div>{item.name}</div> : false
-)}
-
-É uma boa prática usar componentes internos combinados com listas para limpar seu código.
-import Nullstack from "nullstack";
-
-class List extends Nullstack {
- items = [
- { visible: true, number: 1 },
- { visible: false, number: 2 },
- { visible: true, number: 3 },
- ]
-
- renderItem({ visible, number }) {
- if (!visible) return false;
- return <li> {number} </li>
- }
-
- render() {
- return (
- <ul>
- {this.items.map((item) => (
- <Item {...item} />
- ))}
- </ul>
- )
- }
-}
-
-export default List;
-
---✨ Às vezes, você notará chaves no mapa. Saiba mais sobre a key da instância.
-
Você pode definir o HTML interno de um elemento com o atributo html.
Links dentro da string HTML serão substituídos por Âncoras Roteáveis.
-import Nullstack from "nullstack";
-
-class Post extends Nullstack {
-
- content = `
- <h1> Este é um post </h1>
- <a href="/other-post">
- Confira este outro post
- </a>
- `;
-
- render() {
- return (
- <article html={this.content} />
- )
- }
-
-}
-
-export default Post;
-
---🔥 Tome cuidado! Ao usar o HTML gerado pelo usuário, você está em risco de injeção de script
-
headComponentes renderizáveis podem renderizar dentro da tag head um número ilimitado de vezes em qualquer profundidade do aplicativo.
A tag head só será atualizada durante o processo de renderização no servidor e mudanças serão ignorados após o processo de hidratação.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <div>
- <head>
- <link rel="preconnect" href="https://www.googletagmanager.com" />
- </head>
- </div>
- <head>
- <link rel="preload" href="/roboto-v20-latin-300.woff2" as="font" type="font/woff2" crossorigin />
- <link rel="preload" href="/crete-round-v9-latin-regular.woff2" as="font" type="font/woff2" crossorigin />
- </head>
- </main>
- )
- }
-
-}
-
-export default Application;
-
---🔥 Você não deve usar a tag
-headpara atualizar metatags que o Nullstack já controla.
⚔ Adicione estado ao seu componente usando componentes com estado.
-O componente mais simples que você pode fazer é um componente renderizável.
-Componentes renderizáveis são muito semelhantes aos componentes da Web que fornecem a capacidade de criar novas tags HTML que atalham um grupo de outras tags HTML.
-Crie um arquivo em sua pasta src com o nome de seu componente e com a extensão .njs.
Neste exemplo, vai ser chamado helloworld.njs.
Tudo o que você precisa fazer é importar nullstack ou qualquer uma das suas subclasses e estender sua classe dele, definir um método de instância chamado render que retorna qualquer JSX e exporte o componente.
--✨ Instale a extensão oficial Nullstack para VSCode para gerar classes com snippets.
-
import Nullstack from "nullstack";
-
-class HelloWorld extends Nullstack {
-
- render() {
- return (
- <div> Olá Mundo </div>
- )
- }
-
-}
-
-export default HelloWorld;
-
-O código acima apenas declara o componente, você ainda tem que usá-lo.
-Importando o componente em seu aplicativo, temos a capacidade de usar uma nova tag em sua renderização.
-Esta tag será substituída pelo que você retornou no método render do componente.
import Nullstack from "nullstack";
-
-import "./Application.scss";
-
-import HelloWorld from "./HelloWorld";
-
-class Application extends Nullstack {
- // ...
-
- render({ page }) {
- return (
- <main>
- <h1> {page.title} </h1>
- <a href="https://nullstack.app/documentation" target="_blank">
- Read the documentation
- </a>
- <HelloWorld />
- </main>
- )
- }
-}
-
-export default Application;
-
-Nullstack JSX se desvia um pouco das especificações.
-Você pode usar os atributos HTML normais como class e for diretamente.
<label for="input" class="nao-me-rotule"> Eu sou um rótulo </label>
-
-Se você deseja pular a renderização do componente, você pode simplesmente retornar false da renderização.
import Nullstack from "nullstack";
-
-class Headless extends Nullstack {
-
- render() {
- return false;
- }
-
-}
-
-export default Headless;
-
-Isso alocará o espaço no DOM para quando você decidir renderizar a marcação lá.
-Isso também é útil para renderização condicional.
-Se tudo o que você deseja fazer é gerar um componente invisível, você pode ignorar a definição do método de renderização.
-Em vez de criar um novo componente apenas para organizar a divisão de código, você pode criar um componente interno.
-Componentes internos são quaisquer métodos cujo nome seja iniciado com render seguido por um caractere maiúsculo.
Componentes internos compartilham a mesma instância e escopo, pois o componente principal, portanto, são muito convenientes para evitar problemas como adereços de perfuração.
-Para invocar o componente interno, use uma tag JSX com o nome do método sem o prefixo render.
import Nullstack from "nullstack"
-
-class Post extends Nullstack {
-
- renderArticle() {
- return (
- <article> Conteúdo </article>
- )
- }
-
- renderAside() {
- return (
- <aside> Conteúdo Relacionado </aside>
- )
- }
-
- render() {
- return (
- <div>
- <Article />
- <Aside />
- </div>
- )
- }
-
-}
-
-export default HelloWorld;
-
---💡 Nullstack injetará uma referência constante à função no tempo de transpilação, a fim de ignorar completamente o processo de pesquisa de tempo de execução!
-
Os atributos podem ser atribuídos como booleanos.
-Quando o valor é false, o atributo não será renderizado.
Quando o valor for true, ele será processado como um atributo booleano sem um valor de string.
<button disabled={false}> Botão </button>
-
-Você pode abreviar atributos quando sabe que o valor será sempre verdadeiro.
-<button disabled> Botão </button>
-
---✨ Aprender mais sobre atributos.
-
Se você precisar decidir o nome da tag em tempo de execução, pode usar a tag do elemento e definir o atributo da tag condicionalmente.
-<element tag={!!link ? "a" : "span"} href={link || false}>
- algum texto arbitrário
-</element>
-
-Quando o atributo tag é omitido, Nullstack assumirá como padrão um div.
O SVG pode ser usado como se fosse qualquer tag HTML normal.
-Você pode manipular o SVG usando atributos e eventos normalmente.
-<svg height={this.size} viewBox="0 0 100 100">
- <circle cx="50" cy="50" r="40" onclick={this.grow} />
-</svg>
-
---✨ Aprender mais sobre eventos.
-
Seu componente pode ser invocado passando um bloco de conteúdo.
-<Header>
- <h1> Olá Mundo</h1>
-</Header>
-
-Isso não renderiza automaticamente o bloco, pois não saberia onde colocá-lo.
-Você pode desestruturar os filhos no método de renderização e colocá-los em sua marcação.
-import Nullstack from "nullstack";
-
-class Header extends Nullstack {
-
- render({ children }) {
- return (
- <div>{children}</div>
- )
- }
-
-}
-
-export default Header;
-
---✨ Isso é possível porque a chave
-childrenfaz parte do contexto da instância.
Você pode mapear listas sem declarar uma key.
As listas que podem mudar de comprimento devem ser agrupadas em um elemento pai apenas para elas.
-<ul>
- {list.map((item) => (
- <li>{item.name}</li>
- ))}
-</ul>
-
-Você pode emular uma lista de tamanho fixo, retornando false em vez de um elemento para reservar espaço no Dom.
{list.map((item) => (
- item.visible ? <div>{item.name}</div> : false
-)}
-
-É uma boa prática usar componentes internos combinados com listas para limpar seu código.
-import Nullstack from "nullstack";
-
-class List extends Nullstack {
- items = [
- { visible: true, number: 1 },
- { visible: false, number: 2 },
- { visible: true, number: 3 },
- ]
-
- renderItem({ visible, number }) {
- if (!visible) return false;
- return <li> {number} </li>
- }
-
- render() {
- return (
- <ul>
- {this.items.map((item) => (
- <Item {...item} />
- ))}
- </ul>
- )
- }
-}
-
-export default List;
-
---✨ Às vezes, você notará chaves no mapa. Saiba mais sobre a key da instância.
-
Você pode definir o HTML interno de um elemento com o atributo html.
Links dentro da string HTML serão substituídos por Âncoras Roteáveis.
-import Nullstack from "nullstack";
-
-class Post extends Nullstack {
-
- content = `
- <h1> Este é um post </h1>
- <a href="/other-post">
- Confira este outro post
- </a>
- `;
-
- render() {
- return (
- <article html={this.content} />
- )
- }
-
-}
-
-export default Post;
-
---🔥 Tome cuidado! Ao usar o HTML gerado pelo usuário, você está em risco de injeção de script
-
headComponentes renderizáveis podem renderizar dentro da tag head um número ilimitado de vezes em qualquer profundidade do aplicativo.
A tag head só será atualizada durante o processo de renderização no servidor e mudanças serão ignorados após o processo de hidratação.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <div>
- <head>
- <link rel="preconnect" href="https://www.googletagmanager.com" />
- </head>
- </div>
- <head>
- <link rel="preload" href="/roboto-v20-latin-300.woff2" as="font" type="font/woff2" crossorigin />
- <link rel="preload" href="/crete-round-v9-latin-regular.woff2" as="font" type="font/woff2" crossorigin />
- </head>
- </main>
- )
- }
-
-}
-
-export default Application;
-
---🔥 Você não deve usar a tag
-headpara atualizar metatags que o Nullstack já controla.
⚔ Adicione estado ao seu componente usando componentes com estado.
-O componente mais simples que você pode fazer é um componente renderizável.
\nComponentes renderizáveis são muito semelhantes aos componentes da Web que fornecem a capacidade de criar novas tags HTML que atalham um grupo de outras tags HTML.
\nCrie um arquivo em sua pasta src com o nome de seu componente e com a extensão .njs.
Neste exemplo, vai ser chamado helloworld.njs.
Tudo o que você precisa fazer é importar nullstack ou qualquer uma das suas subclasses e estender sua classe dele, definir um método de instância chamado render que retorna qualquer JSX e exporte o componente.
\n\n✨ Instale a extensão oficial Nullstack para VSCode para gerar classes com snippets.
\n
import Nullstack from \"nullstack\";\n\nclass HelloWorld extends Nullstack {\n\n render() {\n return (\n <div> Olá Mundo </div>\n )\n }\n\n}\n\nexport default HelloWorld;\n\nO código acima apenas declara o componente, você ainda tem que usá-lo.
\nImportando o componente em seu aplicativo, temos a capacidade de usar uma nova tag em sua renderização.
\nEsta tag será substituída pelo que você retornou no método render do componente.
import Nullstack from \"nullstack\";\n\nimport \"./Application.scss\";\n\nimport HelloWorld from \"./HelloWorld\";\n\nclass Application extends Nullstack {\n // ...\n\n render({ page }) {\n return (\n <main>\n <h1> {page.title} </h1>\n <a href=\"https://nullstack.app/documentation\" target=\"_blank\">\n Read the documentation\n </a>\n <HelloWorld />\n </main>\n )\n }\n}\n\nexport default Application;\n\nNullstack JSX se desvia um pouco das especificações.
\nVocê pode usar os atributos HTML normais como class e for diretamente.
<label for=\"input\" class=\"nao-me-rotule\"> Eu sou um rótulo </label>\n\nSe você deseja pular a renderização do componente, você pode simplesmente retornar false da renderização.
import Nullstack from \"nullstack\";\n\nclass Headless extends Nullstack {\n\n render() {\n return false;\n }\n\n}\n\nexport default Headless;\n\nIsso alocará o espaço no DOM para quando você decidir renderizar a marcação lá.
\nIsso também é útil para renderização condicional.
\nSe tudo o que você deseja fazer é gerar um componente invisível, você pode ignorar a definição do método de renderização.
\nEm vez de criar um novo componente apenas para organizar a divisão de código, você pode criar um componente interno.
\nComponentes internos são quaisquer métodos cujo nome seja iniciado com render seguido por um caractere maiúsculo.
Componentes internos compartilham a mesma instância e escopo, pois o componente principal, portanto, são muito convenientes para evitar problemas como adereços de perfuração.
\nPara invocar o componente interno, use uma tag JSX com o nome do método sem o prefixo render.
import Nullstack from \"nullstack\"\n\nclass Post extends Nullstack {\n\n renderArticle() {\n return (\n <article> Conteúdo </article>\n )\n }\n\n renderAside() {\n return (\n <aside> Conteúdo Relacionado </aside>\n )\n }\n\n render() {\n return (\n <div>\n <Article />\n <Aside />\n </div>\n )\n }\n\n}\n\nexport default HelloWorld;\n\n\n\n💡 Nullstack injetará uma referência constante à função no tempo de transpilação, a fim de ignorar completamente o processo de pesquisa de tempo de execução!
\n
Os atributos podem ser atribuídos como booleanos.
\nQuando o valor é false, o atributo não será renderizado.
Quando o valor for true, ele será processado como um atributo booleano sem um valor de string.
<button disabled={false}> Botão </button>\n\nVocê pode abreviar atributos quando sabe que o valor será sempre verdadeiro.
\n<button disabled> Botão </button>\n\n\n\n✨ Aprender mais sobre atributos.
\n
Se você precisar decidir o nome da tag em tempo de execução, pode usar a tag do elemento e definir o atributo da tag condicionalmente.
\n<element tag={!!link ? \"a\" : \"span\"} href={link || false}>\n algum texto arbitrário\n</element>\n\nQuando o atributo tag é omitido, Nullstack assumirá como padrão um div.
O SVG pode ser usado como se fosse qualquer tag HTML normal.
\nVocê pode manipular o SVG usando atributos e eventos normalmente.
\n<svg height={this.size} viewBox=\"0 0 100 100\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" onclick={this.grow} />\n</svg>\n\n\n\n✨ Aprender mais sobre eventos.
\n
Seu componente pode ser invocado passando um bloco de conteúdo.
\n<Header>\n <h1> Olá Mundo</h1>\n</Header>\n\nIsso não renderiza automaticamente o bloco, pois não saberia onde colocá-lo.
\nVocê pode desestruturar os filhos no método de renderização e colocá-los em sua marcação.
\nimport Nullstack from \"nullstack\";\n\nclass Header extends Nullstack {\n\n render({ children }) {\n return (\n <div>{children}</div>\n )\n }\n\n}\n\nexport default Header;\n\n\n\n✨ Isso é possível porque a chave
\nchildrenfaz parte do contexto da instância.
Você pode mapear listas sem declarar uma key.
As listas que podem mudar de comprimento devem ser agrupadas em um elemento pai apenas para elas.
\n<ul>\n {list.map((item) => (\n <li>{item.name}</li>\n ))}\n</ul>\n\nVocê pode emular uma lista de tamanho fixo, retornando false em vez de um elemento para reservar espaço no Dom.
{list.map((item) => (\n item.visible ? <div>{item.name}</div> : false\n)}\n\nÉ uma boa prática usar componentes internos combinados com listas para limpar seu código.
\nimport Nullstack from \"nullstack\";\n\nclass List extends Nullstack {\n items = [\n { visible: true, number: 1 },\n { visible: false, number: 2 },\n { visible: true, number: 3 },\n ]\n\n renderItem({ visible, number }) {\n if (!visible) return false;\n return <li> {number} </li>\n }\n\n render() {\n return (\n <ul>\n {this.items.map((item) => (\n <Item {...item} />\n ))}\n </ul>\n )\n }\n}\n\nexport default List;\n\n\n\n✨ Às vezes, você notará chaves no mapa. Saiba mais sobre a key da instância.
\n
Você pode definir o HTML interno de um elemento com o atributo html.
Links dentro da string HTML serão substituídos por Âncoras Roteáveis.
\nimport Nullstack from \"nullstack\";\n\nclass Post extends Nullstack {\n\n content = `\n <h1> Este é um post </h1>\n <a href=\"/other-post\">\n Confira este outro post\n </a>\n `;\n\n render() {\n return (\n <article html={this.content} />\n )\n }\n\n}\n\nexport default Post;\n\n\n\n🔥 Tome cuidado! Ao usar o HTML gerado pelo usuário, você está em risco de injeção de script
\n
headComponentes renderizáveis podem renderizar dentro da tag head um número ilimitado de vezes em qualquer profundidade do aplicativo.
A tag head só será atualizada durante o processo de renderização no servidor e mudanças serão ignorados após o processo de hidratação.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <div>\n <head>\n <link rel=\"preconnect\" href=\"https://www.googletagmanager.com\" />\n </head>\n </div>\n <head>\n <link rel=\"preload\" href=\"/roboto-v20-latin-300.woff2\" as=\"font\" type=\"font/woff2\" crossorigin />\n <link rel=\"preload\" href=\"/crete-round-v9-latin-regular.woff2\" as=\"font\" type=\"font/woff2\" crossorigin />\n </head>\n </main>\n )\n }\n\n}\n\nexport default Application;\n\n\n\n🔥 Você não deve usar a tag
\nheadpara atualizar metatags que o Nullstack já controla.
⚔ Adicione estado ao seu componente usando componentes com estado.
\n","description":"Componentes renderizáveis são muito semelhantes aos componentes da Web que fornecem a capacidade de criar novas tags HTML que atalham um grupo de outras tags HTML"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Componentes renderizáveis - Nullstack","description":"Componentes renderizáveis são muito semelhantes aos componentes da Web que fornecem a capacidade de criar novas tags HTML que atalham um grupo de outras tags HTML"}} \ No newline at end of file diff --git a/docs/pt-br/componentes.html b/docs/pt-br/componentes.html deleted file mode 100644 index df0feba6..00000000 --- a/docs/pt-br/componentes.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - -Uma lista com curadoria de componentes Nullstack feitos pela comunidade.
Se você deseja adicionar um componente a esta lista, abra uma issue no github.
🤘 Nullstack é BR porr@!
Uma lista com curadoria de componentes Nullstack feitos pela comunidade.
Se você deseja adicionar um componente a esta lista, abra uma issue no github.
🤘 Nullstack é BR porr@!
objectEle te dá informações sobre o conjunto de dados do elemento.
-Você pode usar esta chave para evitar poluir seu DOM com atributos inválidos.
---💡 Isso ajuda o Nullstack a definir atributos sem perder tempo validando-os.
-
Quaisquer atributos data-* receberão uma chave camelizada respectiva no objeto data.
Você pode atribuir atributos data ambos via data-* e uma chave data que aceita um objeto com chaves camelizadas.
A versão kebab também está disponível no contexto.
-import Nullstack from "nullstack"
-
-class ContextData extends Nullstack {
- count = 1
-
- calculate({ data }) {
- this.count = this.count * data.multiply + data.sum
- }
-
- renderInner(context) {
- const { data } = context
- return (
- <div data={data}>
- {data.frameworkName}é o mesmo que
- {context["data-framework-name"]}
- </div>
- )
- }
-
- render({ data }) {
- return (
- <div>
- <button onclick={this.calculate} data-multiply={3} data={{ sum: 2 }}>
- Calcular
- </button>
- <Inner data-framework-name="Nullstack" />
- </div>
- )
- }
-}
-
-export default ContextData
-
---💡 Chaves camelizadas do objeto
-dataresultarão em atributos kebab no DOM.
⚔ Aprenda sobre a chave environment do contexto.
objectEle te dá informações sobre o conjunto de dados do elemento.
-Você pode usar esta chave para evitar poluir seu DOM com atributos inválidos.
---💡 Isso ajuda o Nullstack a definir atributos sem perder tempo validando-os.
-
Quaisquer atributos data-* receberão uma chave camelizada respectiva no objeto data.
Você pode atribuir atributos data ambos via data-* e uma chave data que aceita um objeto com chaves camelizadas.
A versão kebab também está disponível no contexto.
-import Nullstack from "nullstack"
-
-class ContextData extends Nullstack {
- count = 1
-
- calculate({ data }) {
- this.count = this.count * data.multiply + data.sum
- }
-
- renderInner(context) {
- const { data } = context
- return (
- <div data={data}>
- {data.frameworkName}é o mesmo que
- {context["data-framework-name"]}
- </div>
- )
- }
-
- render({ data }) {
- return (
- <div>
- <button onclick={this.calculate} data-multiply={3} data={{ sum: 2 }}>
- Calcular
- </button>
- <Inner data-framework-name="Nullstack" />
- </div>
- )
- }
-}
-
-export default ContextData
-
---💡 Chaves camelizadas do objeto
-dataresultarão em atributos kebab no DOM.
⚔ Aprenda sobre a chave environment do contexto.
objectEle te dá informações sobre o conjunto de dados do elemento.
\nVocê pode usar esta chave para evitar poluir seu DOM com atributos inválidos.
\n\n\n💡 Isso ajuda o Nullstack a definir atributos sem perder tempo validando-os.
\n
Quaisquer atributos data-* receberão uma chave camelizada respectiva no objeto data.
Você pode atribuir atributos data ambos via data-* e uma chave data que aceita um objeto com chaves camelizadas.
A versão kebab também está disponível no contexto.
\nimport Nullstack from \"nullstack\"\n\nclass ContextData extends Nullstack {\n count = 1\n\n calculate({ data }) {\n this.count = this.count * data.multiply + data.sum\n }\n\n renderInner(context) {\n const { data } = context\n return (\n <div data={data}>\n {data.frameworkName}é o mesmo que\n {context[\"data-framework-name\"]}\n </div>\n )\n }\n\n render({ data }) {\n return (\n <div>\n <button onclick={this.calculate} data-multiply={3} data={{ sum: 2 }}>\n Calcular\n </button>\n <Inner data-framework-name=\"Nullstack\" />\n </div>\n )\n }\n}\n\nexport default ContextData\n\n\n\n💡 Chaves camelizadas do objeto
\ndataresultarão em atributos kebab no DOM.
⚔ Aprenda sobre a chave environment do contexto.
objectEle te dá informações sobre o ambiente atual.
-As seguintes chaves estão disponíveis no objeto:
-booleanbooleanbooleanbooleanbooleanstringimport Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- render({environment}) {
- return (
- <div>
- {environment.client && <p>Estou no cliente</p>}
- {environment.server && <p>Estou no servidor</p>}
- {environment.development && <p>Estou em modo de desenvolvimento</p>}
- {environment.production && <p>Estou em modo de produção</p>}
- {environment.static && <p>Estou em um site estático</p>}
- <p>Minha chave é {environment.key}</p>
- </div>
- )
- }
-
-}
-
-export default Page;
-
-A chave key do environment é um hash md5 das saídas da pasta do ambiente atual. A key é anexada nos caminhos dos assets e na API estática para auxiliar no controle de cache.
⚔ Aprenda sobre a chave page do contexto.
objectEle te dá informações sobre o ambiente atual.
-As seguintes chaves estão disponíveis no objeto:
-booleanbooleanbooleanbooleanbooleanstringimport Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- render({environment}) {
- return (
- <div>
- {environment.client && <p>Estou no cliente</p>}
- {environment.server && <p>Estou no servidor</p>}
- {environment.development && <p>Estou em modo de desenvolvimento</p>}
- {environment.production && <p>Estou em modo de produção</p>}
- {environment.static && <p>Estou em um site estático</p>}
- <p>Minha chave é {environment.key}</p>
- </div>
- )
- }
-
-}
-
-export default Page;
-
-A chave key do environment é um hash md5 das saídas da pasta do ambiente atual. A key é anexada nos caminhos dos assets e na API estática para auxiliar no controle de cache.
⚔ Aprenda sobre a chave page do contexto.
objectEle te dá informações sobre o ambiente atual.
\nAs seguintes chaves estão disponíveis no objeto:
\nbooleanbooleanbooleanbooleanbooleanstringimport Nullstack from 'nullstack';\n\nclass Page extends Nullstack {\n \n render({environment}) {\n return (\n <div> \n {environment.client && <p>Estou no cliente</p>}\n {environment.server && <p>Estou no servidor</p>}\n {environment.development && <p>Estou em modo de desenvolvimento</p>}\n {environment.production && <p>Estou em modo de produção</p>}\n {environment.static && <p>Estou em um site estático</p>}\n <p>Minha chave é {environment.key}</p>\n </div>\n )\n }\n\n}\n\nexport default Page;\n\nA chave key do environment é um hash md5 das saídas da pasta do ambiente atual. A key é anexada nos caminhos dos assets e na API estática para auxiliar no controle de cache.
⚔ Aprenda sobre a chave page do contexto.
objectEle fornece informações sobre as metatags da head do documento.
Chaves de page serão usadas para gerar as metatags durante a renderização no lado do servidor e devem ser atribuídas antes do ciclo initiate ser resolvido.
As seguintes chaves estão disponíveis no objeto:
-stringstring (URL absoluto ou relativo)stringstring (URL absoluto ou relativo)stringstringobjectstringnumbernumberQuando a chave title é atribuída no lado do client, o título do documento será atualizado.
Nullstack utiliza as chaves changes e priority para gerar o sitemap.xml.
O mapa do site é gerado automaticamente apenas ao utilizar a geração de site estático e deve ser gerado manualmente em aplicativos com a renderização no lado do servidor.
-A chave changes representa a chave changefreq no sitemap.xml e se for atribuída deverá ser um dos seguintes valores:
A chave priority é um número entre 0.0 e 1.0 que representa a chave priority no sitemap.xml.
Nullstack não define uma prioridade padrão, no entanto, sitemaps assumem uma prioridade 0.5 quando não são definidas explicitamente.
Além de title e locale, todas as outras chaves tem padrões sensíveis e gerados com base no escopo do aplicativo.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- prepare({project, page}) {
- page.title = `${project.name} - Título da página`;
- page.image = '/imagem.jpg';
- page.description = 'Meta descrição da página';
- page.canonical = 'http://absoluto.url/canonical-link';
- page.locale = 'pt-BR';
- page.robots = 'index, follow';
- page.schema = {};
- page.changes = 'weekly';
- page.priority = 1;
- }
-
- render({page}) {
- return (
- <div>
- <h1>{page.title}</h1>
- <p>{page.description}</p>
- </div>
- )
- }
-
-}
-
-export default Page;
-
-Atualizando page.title gerará um evento personalizado.
import Nullstack from 'nullstack';
-
-class Analytics extends Nullstack {
-
- hydrate({page}) {
- window.addEventListener(page.event, () => {
- console.log(page.title);
- });
- }
-
-}
-
-export default Analytics;
-
-Se durante o processo de renderização no lado do servidor o page.status estiver com qualquer valor além de 200, seu aplicativo receberá outra passagem na renderização e lhe possibilitará ajustar a interface de acordo com o status retornado.
A chave status será gerada na resposta HTTP.
O status da página será modificado para 500 e receberá outra passagem na renderização se a página gerar uma exceção enquanto renderiza.
O status das respostas de funções do servidor será definido no page.status.
import Nullstack from 'nullstack';
-import ErrorPage from './ErrorPage';
-import HomePage from './HomePage';
-
-class Application extends Nullstack {
-
- // ...
-
- render({page}) {
- return (
- <main>
- {page.status !== 200 && <ErrorPage route="*" />}
- <HomePage route="/" />
- </main>
- )
- }
-
-}
-
-export default Application;
-
---🔥 A atribuição à chave
-statusdurante o modo aplicativo de página única não terá efeito.
⚔ Aprenda sobre a chave project do contexto.
objectEle fornece informações sobre as metatags da head do documento.
Chaves de page serão usadas para gerar as metatags durante a renderização no lado do servidor e devem ser atribuídas antes do ciclo initiate ser resolvido.
As seguintes chaves estão disponíveis no objeto:
-stringstring (URL absoluto ou relativo)stringstring (URL absoluto ou relativo)stringstringobjectstringnumbernumberQuando a chave title é atribuída no lado do client, o título do documento será atualizado.
Nullstack utiliza as chaves changes e priority para gerar o sitemap.xml.
O mapa do site é gerado automaticamente apenas ao utilizar a geração de site estático e deve ser gerado manualmente em aplicativos com a renderização no lado do servidor.
-A chave changes representa a chave changefreq no sitemap.xml e se for atribuída deverá ser um dos seguintes valores:
A chave priority é um número entre 0.0 e 1.0 que representa a chave priority no sitemap.xml.
Nullstack não define uma prioridade padrão, no entanto, sitemaps assumem uma prioridade 0.5 quando não são definidas explicitamente.
Além de title e locale, todas as outras chaves tem padrões sensíveis e gerados com base no escopo do aplicativo.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- prepare({project, page}) {
- page.title = `${project.name} - Título da página`;
- page.image = '/imagem.jpg';
- page.description = 'Meta descrição da página';
- page.canonical = 'http://absoluto.url/canonical-link';
- page.locale = 'pt-BR';
- page.robots = 'index, follow';
- page.schema = {};
- page.changes = 'weekly';
- page.priority = 1;
- }
-
- render({page}) {
- return (
- <div>
- <h1>{page.title}</h1>
- <p>{page.description}</p>
- </div>
- )
- }
-
-}
-
-export default Page;
-
-Atualizando page.title gerará um evento personalizado.
import Nullstack from 'nullstack';
-
-class Analytics extends Nullstack {
-
- hydrate({page}) {
- window.addEventListener(page.event, () => {
- console.log(page.title);
- });
- }
-
-}
-
-export default Analytics;
-
-Se durante o processo de renderização no lado do servidor o page.status estiver com qualquer valor além de 200, seu aplicativo receberá outra passagem na renderização e lhe possibilitará ajustar a interface de acordo com o status retornado.
A chave status será gerada na resposta HTTP.
O status da página será modificado para 500 e receberá outra passagem na renderização se a página gerar uma exceção enquanto renderiza.
O status das respostas de funções do servidor será definido no page.status.
import Nullstack from 'nullstack';
-import ErrorPage from './ErrorPage';
-import HomePage from './HomePage';
-
-class Application extends Nullstack {
-
- // ...
-
- render({page}) {
- return (
- <main>
- {page.status !== 200 && <ErrorPage route="*" />}
- <HomePage route="/" />
- </main>
- )
- }
-
-}
-
-export default Application;
-
---🔥 A atribuição à chave
-statusdurante o modo aplicativo de página única não terá efeito.
⚔ Aprenda sobre a chave project do contexto.
objectEle fornece informações sobre as metatags da head do documento.
Chaves de page serão usadas para gerar as metatags durante a renderização no lado do servidor e devem ser atribuídas antes do ciclo initiate ser resolvido.
As seguintes chaves estão disponíveis no objeto:
\nstringstring (URL absoluto ou relativo)stringstring (URL absoluto ou relativo)stringstringobjectstringnumbernumberQuando a chave title é atribuída no lado do client, o título do documento será atualizado.
Nullstack utiliza as chaves changes e priority para gerar o sitemap.xml.
O mapa do site é gerado automaticamente apenas ao utilizar a geração de site estático e deve ser gerado manualmente em aplicativos com a renderização no lado do servidor.
\nA chave changes representa a chave changefreq no sitemap.xml e se for atribuída deverá ser um dos seguintes valores:
A chave priority é um número entre 0.0 e 1.0 que representa a chave priority no sitemap.xml.
Nullstack não define uma prioridade padrão, no entanto, sitemaps assumem uma prioridade 0.5 quando não são definidas explicitamente.
Além de title e locale, todas as outras chaves tem padrões sensíveis e gerados com base no escopo do aplicativo.
import Nullstack from 'nullstack';\n\nclass Page extends Nullstack {\n\n prepare({project, page}) {\n page.title = `${project.name} - Título da página`;\n page.image = '/imagem.jpg';\n page.description = 'Meta descrição da página';\n page.canonical = 'http://absoluto.url/canonical-link';\n page.locale = 'pt-BR';\n page.robots = 'index, follow';\n page.schema = {};\n page.changes = 'weekly';\n page.priority = 1;\n }\n\n render({page}) {\n return (\n <div>\n <h1>{page.title}</h1>\n <p>{page.description}</p>\n </div>\n )\n }\n\n}\n\nexport default Page;\n\nAtualizando page.title gerará um evento personalizado.
import Nullstack from 'nullstack';\n\nclass Analytics extends Nullstack {\n\n hydrate({page}) {\n window.addEventListener(page.event, () => {\n console.log(page.title);\n });\n }\n\n}\n\nexport default Analytics;\n\nSe durante o processo de renderização no lado do servidor o page.status estiver com qualquer valor além de 200, seu aplicativo receberá outra passagem na renderização e lhe possibilitará ajustar a interface de acordo com o status retornado.
A chave status será gerada na resposta HTTP.
O status da página será modificado para 500 e receberá outra passagem na renderização se a página gerar uma exceção enquanto renderiza.
O status das respostas de funções do servidor será definido no page.status.
import Nullstack from 'nullstack';\nimport ErrorPage from './ErrorPage';\nimport HomePage from './HomePage';\n\nclass Application extends Nullstack {\n\n // ...\n\n render({page}) {\n return (\n <main>\n {page.status !== 200 && <ErrorPage route=\"*\" />}\n <HomePage route=\"/\" />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\n\n\n🔥 A atribuição à chave
\nstatusdurante o modo aplicativo de página única não terá efeito.
⚔ Aprenda sobre a chave project do contexto.
objectEle te dá informações sobre o manifest do app e algumas metatags.
-As chaves de project serão usadas para gerar metatags durante a renderização do lado do servidor e devem ser definidas antes que initiate seja resolvido.
As chaves de project serão usadas para gerar o manifest do app e devem ser definidas durante a inicialização da aplicação.
A chave disallow será usada para gerar o robots.txt e deverá ser definida durante a inicialização da aplicação.
As chaves de project serão congeladas após a inicialização da aplicação.
As chaves a seguir estão disponíveis no objeto:
-stringstringstringstringstringstringstringstringstringstringobjectstring (url relativo ou absoluto)array de string (caminhos relativos)boolean ou string (url relativo ou absoluto)string (url absoluto)string (http or https)Além de domain, name and color todas as outras chaves tem padrões sensíveis gerados com base no escopo do aplicativo.
Se você não declarar a chave icons, Nullstack irá escanear quaisquer ícones com o nome seguindo o padrão "icon-[LARGURA]x[ALTURA].png" na sua pasta public.
Se a chave sitemap estiver definida como true o seu arquivo robots.txt irá apontar o sitemap para https://${project.domain}/sitemap.xml.
A chave cdn irá prefixar seu pacote de assets e ficará disponível no contexto para que você possa manualmente prefixar outros ativos.
A chave protocol é "http" no modo de desenvolvimento e "https" e no modo produção por predefinição.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({project}) {
- project.name = 'Nullstack';
- project.shortName = 'Nullstack';
- project.domain = 'nullstack.app';
- project.color = '#d22365';
- project.backgroundColor = '#d22365';
- project.type = 'website';
- project.display = 'standalone';
- project.orientation = 'portrait';
- project.scope = '/';
- project.root = '/';
- project.icons = {
- '72': '/icon-72x72.png',
- '128': '/icon-128x128.png',
- '512': '/icon-512x512.png'
- };
- project.favicon = '/favicon.png';
- project.disallow = ['/admin'];
- project.sitemap = true;
- project.cdn = 'cdn.nullstack.app';
- project.protocol = 'https';
- }
-
- prepare({project, page}) {
- page.title = project.name;
- }
-
-}
-
-export default Application;
-
---💡 Você pode substituir o manifest.json gerado automaticamente e robots.txt inserindo o seu próprio arquivo na pasta public
-
⚔ Aprenda sobre a chave settings do contexto.
objectEle te dá informações sobre o manifest do app e algumas metatags.
-As chaves de project serão usadas para gerar metatags durante a renderização do lado do servidor e devem ser definidas antes que initiate seja resolvido.
As chaves de project serão usadas para gerar o manifest do app e devem ser definidas durante a inicialização da aplicação.
A chave disallow será usada para gerar o robots.txt e deverá ser definida durante a inicialização da aplicação.
As chaves de project serão congeladas após a inicialização da aplicação.
As chaves a seguir estão disponíveis no objeto:
-stringstringstringstringstringstringstringstringstringstringobjectstring (url relativo ou absoluto)array de string (caminhos relativos)boolean ou string (url relativo ou absoluto)string (url absoluto)string (http or https)Além de domain, name and color todas as outras chaves tem padrões sensíveis gerados com base no escopo do aplicativo.
Se você não declarar a chave icons, Nullstack irá escanear quaisquer ícones com o nome seguindo o padrão "icon-[LARGURA]x[ALTURA].png" na sua pasta public.
Se a chave sitemap estiver definida como true o seu arquivo robots.txt irá apontar o sitemap para https://${project.domain}/sitemap.xml.
A chave cdn irá prefixar seu pacote de assets e ficará disponível no contexto para que você possa manualmente prefixar outros ativos.
A chave protocol é "http" no modo de desenvolvimento e "https" e no modo produção por predefinição.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({project}) {
- project.name = 'Nullstack';
- project.shortName = 'Nullstack';
- project.domain = 'nullstack.app';
- project.color = '#d22365';
- project.backgroundColor = '#d22365';
- project.type = 'website';
- project.display = 'standalone';
- project.orientation = 'portrait';
- project.scope = '/';
- project.root = '/';
- project.icons = {
- '72': '/icon-72x72.png',
- '128': '/icon-128x128.png',
- '512': '/icon-512x512.png'
- };
- project.favicon = '/favicon.png';
- project.disallow = ['/admin'];
- project.sitemap = true;
- project.cdn = 'cdn.nullstack.app';
- project.protocol = 'https';
- }
-
- prepare({project, page}) {
- page.title = project.name;
- }
-
-}
-
-export default Application;
-
---💡 Você pode substituir o manifest.json gerado automaticamente e robots.txt inserindo o seu próprio arquivo na pasta public
-
⚔ Aprenda sobre a chave settings do contexto.
objectEle te dá informações sobre o manifest do app e algumas metatags.
\nAs chaves de project serão usadas para gerar metatags durante a renderização do lado do servidor e devem ser definidas antes que initiate seja resolvido.
As chaves de project serão usadas para gerar o manifest do app e devem ser definidas durante a inicialização da aplicação.
A chave disallow será usada para gerar o robots.txt e deverá ser definida durante a inicialização da aplicação.
As chaves de project serão congeladas após a inicialização da aplicação.
As chaves a seguir estão disponíveis no objeto:
\nstringstringstringstringstringstringstringstringstringstringobjectstring (url relativo ou absoluto)array de string (caminhos relativos)boolean ou string (url relativo ou absoluto)string (url absoluto)string (http or https)Além de domain, name and color todas as outras chaves tem padrões sensíveis gerados com base no escopo do aplicativo.
Se você não declarar a chave icons, Nullstack irá escanear quaisquer ícones com o nome seguindo o padrão "icon-[LARGURA]x[ALTURA].png" na sua pasta public.
Se a chave sitemap estiver definida como true o seu arquivo robots.txt irá apontar o sitemap para https://${project.domain}/sitemap.xml.
A chave cdn irá prefixar seu pacote de assets e ficará disponível no contexto para que você possa manualmente prefixar outros ativos.
A chave protocol é "http" no modo de desenvolvimento e "https" e no modo produção por predefinição.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({project}) {\n project.name = 'Nullstack';\n project.shortName = 'Nullstack';\n project.domain = 'nullstack.app';\n project.color = '#d22365';\n project.backgroundColor = '#d22365';\n project.type = 'website';\n project.display = 'standalone';\n project.orientation = 'portrait';\n project.scope = '/';\n project.root = '/';\n project.icons = {\n '72': '/icon-72x72.png',\n '128': '/icon-128x128.png',\n '512': '/icon-512x512.png'\n };\n project.favicon = '/favicon.png';\n project.disallow = ['/admin'];\n project.sitemap = true;\n project.cdn = 'cdn.nullstack.app';\n project.protocol = 'https';\n }\n\n prepare({project, page}) {\n page.title = project.name;\n }\n\n}\n\nexport default Application;\n\n\n\n💡 Você pode substituir o manifest.json gerado automaticamente e robots.txt inserindo o seu próprio arquivo na pasta public
\n
⚔ Aprenda sobre a chave settings do contexto.
objectVocê pode usá-lo para configurar dados sensíveis para sua aplicação.
-Chaves de secrets são congeladas depois da inicialização da aplicação.
As seguintes chaves estão disponíveis no objeto:
-objectobjectanyVocê pode definir chaves diferentes para as chaves development e production, obtendo assim valores diferentes para cada ambiente.
Caso uma chave seja definida diretamente no objeto secrets ela ficará disponível para ambos os ambientes.
A leitura das chaves deve ser feita diretamente do objeto secrets, pois o Nullstack vai retornar o valor referido de acordo com o ambiente.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({secrets}) {
- secrets.development.privateKey = 'SANDBOX_API_KEY';
- secrets.production.privateKey = 'PRODUCTION_API_KEY';
- secrets.endpoint = 'https://domain.com/api';
- }
-
- static async fetchFromApi({secrets}) {
- const response = await fetch(secrets.endpoint, {
- headers: {
- Authorization: `Bearer ${secrets.privateKey}`
- }
- });
- return await response.json();
- }
-
-}
-
-export default Application;
-
-Qualquer chave de ambiente iniciada por NULLSTACK_SECRETS_ será mapeada para o secrets de seu respectivo ambiente.
---🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY será mapeada para
-secrets.privateKey
⚔ Aprendendo sobre o self da instância.
objectVocê pode usá-lo para configurar dados sensíveis para sua aplicação.
-Chaves de secrets são congeladas depois da inicialização da aplicação.
As seguintes chaves estão disponíveis no objeto:
-objectobjectanyVocê pode definir chaves diferentes para as chaves development e production, obtendo assim valores diferentes para cada ambiente.
Caso uma chave seja definida diretamente no objeto secrets ela ficará disponível para ambos os ambientes.
A leitura das chaves deve ser feita diretamente do objeto secrets, pois o Nullstack vai retornar o valor referido de acordo com o ambiente.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({secrets}) {
- secrets.development.privateKey = 'SANDBOX_API_KEY';
- secrets.production.privateKey = 'PRODUCTION_API_KEY';
- secrets.endpoint = 'https://domain.com/api';
- }
-
- static async fetchFromApi({secrets}) {
- const response = await fetch(secrets.endpoint, {
- headers: {
- Authorization: `Bearer ${secrets.privateKey}`
- }
- });
- return await response.json();
- }
-
-}
-
-export default Application;
-
-Qualquer chave de ambiente iniciada por NULLSTACK_SECRETS_ será mapeada para o secrets de seu respectivo ambiente.
---🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY será mapeada para
-secrets.privateKey
⚔ Aprendendo sobre o self da instância.
objectVocê pode usá-lo para configurar dados sensíveis para sua aplicação.
\nChaves de secrets são congeladas depois da inicialização da aplicação.
As seguintes chaves estão disponíveis no objeto:
\nobjectobjectanyVocê pode definir chaves diferentes para as chaves development e production, obtendo assim valores diferentes para cada ambiente.
Caso uma chave seja definida diretamente no objeto secrets ela ficará disponível para ambos os ambientes.
A leitura das chaves deve ser feita diretamente do objeto secrets, pois o Nullstack vai retornar o valor referido de acordo com o ambiente.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({secrets}) {\n secrets.development.privateKey = 'SANDBOX_API_KEY';\n secrets.production.privateKey = 'PRODUCTION_API_KEY';\n secrets.endpoint = 'https://domain.com/api';\n }\n\n static async fetchFromApi({secrets}) {\n const response = await fetch(secrets.endpoint, {\n headers: {\n Authorization: `Bearer ${secrets.privateKey}`\n }\n });\n return await response.json();\n }\n\n}\n\nexport default Application;\n\nQualquer chave de ambiente iniciada por NULLSTACK_SECRETS_ será mapeada para o secrets de seu respectivo ambiente.
\n\n\n🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY será mapeada para
\nsecrets.privateKey
⚔ Aprendendo sobre o self da instância.
objectVocê pode usá-lo para configurar seu aplicativo com informações públicas.
-Chaves de settings serão congeladas após a inicialização do aplicativo.
As chaves a seguir estão disponíveis no objeto:
-objectobjectanyVocê pode declarar as chaves para as chaves development ou production para ter diferentes configurações por ambiente.
Se você declarar uma chave diretamente para o objeto settings ela ficará disponível em ambos os ambientes.
Quando lendo de uma chave você deve ler diretamente do objeto settings e o Nullstack retornará o valor mais adequado para aquele ambiente.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({settings}) {
- settings.development.publicKey = 'SANDBOX_API_KEY';
- settings.production.publicKey = 'PRODUCTION_API_KEY';
- settings.endpoint = 'https://domain.com/api';
- }
-
- async hydrate({settings}) {
- const response = await fetch(settings.endpoint, {
- headers: {
- Authorization: `Bearer ${settings.publicKey}`
- }
- });
- this.data = await response.json();
- }
-
-}
-
-export default Application;
-
-Qualquer chave de ambiente começando com NULLSTACK_SETTINGS_ será mapeado para as confirgurações daquele ambiente.
---🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY será mapeado para
-settings.publicKey
⚔ Aprenda sobre a chave secrets do contexto.
objectVocê pode usá-lo para configurar seu aplicativo com informações públicas.
-Chaves de settings serão congeladas após a inicialização do aplicativo.
As chaves a seguir estão disponíveis no objeto:
-objectobjectanyVocê pode declarar as chaves para as chaves development ou production para ter diferentes configurações por ambiente.
Se você declarar uma chave diretamente para o objeto settings ela ficará disponível em ambos os ambientes.
Quando lendo de uma chave você deve ler diretamente do objeto settings e o Nullstack retornará o valor mais adequado para aquele ambiente.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({settings}) {
- settings.development.publicKey = 'SANDBOX_API_KEY';
- settings.production.publicKey = 'PRODUCTION_API_KEY';
- settings.endpoint = 'https://domain.com/api';
- }
-
- async hydrate({settings}) {
- const response = await fetch(settings.endpoint, {
- headers: {
- Authorization: `Bearer ${settings.publicKey}`
- }
- });
- this.data = await response.json();
- }
-
-}
-
-export default Application;
-
-Qualquer chave de ambiente começando com NULLSTACK_SETTINGS_ será mapeado para as confirgurações daquele ambiente.
---🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY será mapeado para
-settings.publicKey
⚔ Aprenda sobre a chave secrets do contexto.
objectVocê pode usá-lo para configurar seu aplicativo com informações públicas.
\nChaves de settings serão congeladas após a inicialização do aplicativo.
As chaves a seguir estão disponíveis no objeto:
\nobjectobjectanyVocê pode declarar as chaves para as chaves development ou production para ter diferentes configurações por ambiente.
Se você declarar uma chave diretamente para o objeto settings ela ficará disponível em ambos os ambientes.
Quando lendo de uma chave você deve ler diretamente do objeto settings e o Nullstack retornará o valor mais adequado para aquele ambiente.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({settings}) {\n settings.development.publicKey = 'SANDBOX_API_KEY';\n settings.production.publicKey = 'PRODUCTION_API_KEY';\n settings.endpoint = 'https://domain.com/api';\n }\n\n async hydrate({settings}) {\n const response = await fetch(settings.endpoint, {\n headers: {\n Authorization: `Bearer ${settings.publicKey}`\n }\n });\n this.data = await response.json();\n }\n\n}\n\nexport default Application;\n\nQualquer chave de ambiente começando com NULLSTACK_SETTINGS_ será mapeado para as confirgurações daquele ambiente.
\n\n\n🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY será mapeado para
\nsettings.publicKey
⚔ Aprenda sobre a chave secrets do contexto.
Cada função no Nullstack recebe um contexto como argumento.
-Existem dois contextos, um para o cliente e outro para o servidor.
-O contexto do cliente dura enquanto a guia do navegador estiver aberta.
-O contexto do servidor dura enquanto o servidor estiver em execução.
-Ambos os contextos são proxies que mesclam as chaves de 3 objetos:
-Essas são as informações que o framework disponibiliza para você por padrão.
-Quando você define uma chave para o contexto, ela fica disponível para desestruturação em qualquer profundidade da aplicação, até mesmo para os objetos pais ou aplicações de terceiros que montam seu componente.
-Atualizar uma chave no contexto faz com que a aplicação seja renderizada novamente automaticamente.
-Você pode pensar nisso como um único conceito para substituir stores, contexts, services, e reducers ao mesmo tempo, usando o padrão de injeção de dependência com objetos javascript padrão.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- prepare(context) {
- context.count = 1;
- }
-
- static async updateTotalCount(context) {
- context.totalCount += context.count;
- }
-
- async double(context) {
- context.count += context.count;
- await this.updateTotalCount();
- }
-
- render({count}) {
- return (
- <button onclick={this.double}> {count} </button>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- static async start(context) {
- context.totalCount = 0;
- }
-
- render({count}) {
- return (
- <main>
- {(!count || count < 10) && <Counter />}
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Este contém os atributos que você declara em sua tag, incluindo os data.
Se o atributo é declarado em uma tag componente cada função desse componente terá acesso a esse atributo em seu contexto.
-Se o atributo for declarado em uma tag que possui um evento, ele será incorporado ao contexto da função de evento.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- add(context) {
- context.count += context.delta + context.amount;
- }
-
- render({count, delta}) {
- return (
- <button onclick={this.add} amount={1}>
- adicionar {delta} em {count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- prepare(context) {
- context.count = 0;
- }
-
- render() {
- return (
- <main>
- <Counter delta={2} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Cada função das subclasses do Nullstack é injetada com uma cópia do contexto da instância mesclada com seus argumentos.
-Os argumentos são opcionais, mas se declarados, devem ser um único objeto com chaves de sua escolha.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- add(context) {
- context.count += context.amount || 1;
- }
-
- prepare(context) {
- context.count = 0;
- this.add(); // soma 1
- this.add({amount: 2}); // soma 2
- }
-
- async initiate(context) {
- console.log(context.count); // 3
- }
-
-}
-
-export default Counter;
-
-⚔ Aprenda sobre Rotas e Parâmetros.
-Cada função no Nullstack recebe um contexto como argumento.
-Existem dois contextos, um para o cliente e outro para o servidor.
-O contexto do cliente dura enquanto a guia do navegador estiver aberta.
-O contexto do servidor dura enquanto o servidor estiver em execução.
-Ambos os contextos são proxies que mesclam as chaves de 3 objetos:
-Essas são as informações que o framework disponibiliza para você por padrão.
-Quando você define uma chave para o contexto, ela fica disponível para desestruturação em qualquer profundidade da aplicação, até mesmo para os objetos pais ou aplicações de terceiros que montam seu componente.
-Atualizar uma chave no contexto faz com que a aplicação seja renderizada novamente automaticamente.
-Você pode pensar nisso como um único conceito para substituir stores, contexts, services, e reducers ao mesmo tempo, usando o padrão de injeção de dependência com objetos javascript padrão.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- prepare(context) {
- context.count = 1;
- }
-
- static async updateTotalCount(context) {
- context.totalCount += context.count;
- }
-
- async double(context) {
- context.count += context.count;
- await this.updateTotalCount();
- }
-
- render({count}) {
- return (
- <button onclick={this.double}> {count} </button>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- static async start(context) {
- context.totalCount = 0;
- }
-
- render({count}) {
- return (
- <main>
- {(!count || count < 10) && <Counter />}
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Este contém os atributos que você declara em sua tag, incluindo os data.
Se o atributo é declarado em uma tag componente cada função desse componente terá acesso a esse atributo em seu contexto.
-Se o atributo for declarado em uma tag que possui um evento, ele será incorporado ao contexto da função de evento.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- add(context) {
- context.count += context.delta + context.amount;
- }
-
- render({count, delta}) {
- return (
- <button onclick={this.add} amount={1}>
- adicionar {delta} em {count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- prepare(context) {
- context.count = 0;
- }
-
- render() {
- return (
- <main>
- <Counter delta={2} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Cada função das subclasses do Nullstack é injetada com uma cópia do contexto da instância mesclada com seus argumentos.
-Os argumentos são opcionais, mas se declarados, devem ser um único objeto com chaves de sua escolha.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- add(context) {
- context.count += context.amount || 1;
- }
-
- prepare(context) {
- context.count = 0;
- this.add(); // soma 1
- this.add({amount: 2}); // soma 2
- }
-
- async initiate(context) {
- console.log(context.count); // 3
- }
-
-}
-
-export default Counter;
-
-⚔ Aprenda sobre Rotas e Parâmetros.
-Cada função no Nullstack recebe um contexto como argumento.
\nExistem dois contextos, um para o cliente e outro para o servidor.
\nO contexto do cliente dura enquanto a guia do navegador estiver aberta.
\nO contexto do servidor dura enquanto o servidor estiver em execução.
\nAmbos os contextos são proxies que mesclam as chaves de 3 objetos:
\nEssas são as informações que o framework disponibiliza para você por padrão.
\nQuando você define uma chave para o contexto, ela fica disponível para desestruturação em qualquer profundidade da aplicação, até mesmo para os objetos pais ou aplicações de terceiros que montam seu componente.
\nAtualizar uma chave no contexto faz com que a aplicação seja renderizada novamente automaticamente.
\nVocê pode pensar nisso como um único conceito para substituir stores, contexts, services, e reducers ao mesmo tempo, usando o padrão de injeção de dependência com objetos javascript padrão.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n prepare(context) {\n context.count = 1;\n }\n\n static async updateTotalCount(context) {\n context.totalCount += context.count;\n }\n\n async double(context) {\n context.count += context.count;\n await this.updateTotalCount();\n }\n\n render({count}) {\n return (\n <button onclick={this.double}> {count} </button>\n )\n }\n\n}\n\nexport default Counter;\n\nimport Nullstack from 'nullstack';\nimport Counter from './Counter';\n\nclass Application extends Nullstack {\n\n static async start(context) {\n context.totalCount = 0;\n }\n\n render({count}) {\n return (\n <main>\n {(!count || count < 10) && <Counter />}\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nEste contém os atributos que você declara em sua tag, incluindo os data.
Se o atributo é declarado em uma tag componente cada função desse componente terá acesso a esse atributo em seu contexto.
\nSe o atributo for declarado em uma tag que possui um evento, ele será incorporado ao contexto da função de evento.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n add(context) {\n context.count += context.delta + context.amount;\n }\n\n render({count, delta}) {\n return (\n <button onclick={this.add} amount={1}>\n adicionar {delta} em {count}\n </button>\n )\n }\n\n}\n\nexport default Counter;\n\nimport Nullstack from 'nullstack';\nimport Counter from './Counter';\n\nclass Application extends Nullstack {\n\n prepare(context) {\n context.count = 0;\n }\n\n render() {\n return (\n <main>\n <Counter delta={2} />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nCada função das subclasses do Nullstack é injetada com uma cópia do contexto da instância mesclada com seus argumentos.
\nOs argumentos são opcionais, mas se declarados, devem ser um único objeto com chaves de sua escolha.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n add(context) {\n context.count += context.amount || 1;\n }\n\n prepare(context) {\n context.count = 0;\n this.add(); // soma 1\n this.add({amount: 2}); // soma 2\n }\n\n async initiate(context) {\n console.log(context.count); // 3\n }\n\n}\n\nexport default Counter;\n\n⚔ Aprenda sobre Rotas e Parâmetros.
\n","description":"Cada função no Nullstack recebe um contexto como argumento."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Contexto - Nullstack","description":"Cada função no Nullstack recebe um contexto como argumento."}} \ No newline at end of file diff --git a/docs/pt-br/contribuidores.html b/docs/pt-br/contribuidores.html deleted file mode 100644 index 8765aa04..00000000 --- a/docs/pt-br/contribuidores.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - -O Nullstack está sendo desenvolvido desde janeiro de 2019 com recursos sendo extraídos de projetos freelance.
Nesse ponto, a API está estável, os métodos de ciclo de vida e as chaves de contexto estarão praticamente congelados.
Ainda não estamos na v1.0, mas muito perto, a única coisa que falta é testá-lo em aplicativos feitos fora da equipe principal para descobrir se ele atende às necessidades de outros programadores.
As próximas atualizações serão direcionadas a correções de quaisquer bugs encontrados e terão foco na qualidade de vida.
As atualizações listadas nas issues do Nullstack são as próximas etapas planejadas sem nenhuma ordem específica.
O Nullstack foi desenvolvido por freelancers full-stacks neuroatípicos.
Com um histórico pesado em Rails, Ember.js, React.js e filosofia Vue.js as inspirações tiradas desses projetos podem ser óbvias.

Criador do conceito. Vai com novas propostas de API para seus patos de borracha favoritos e retorna com commits.
Fez a engenharia reversa de código de pensamento positivo para sua existência e depois o refatorou em um framework.

Pato de borracha com habilidades humanas, garante que o código não saia muito pra fora da caixa, então faz a caixa parecer legal.
Revisor de API que desenvolveu projetos de terceiros para testar a prova de conceitos de uma perspectiva focada no front-end.

Pato de borracha com um pescoço para encontrar inconsistências e problemas, esperando até que uma API seja aprovada para nos forçar a reescrever tudo.
Adotante antecipada do framework que desenvolveu aplicações reais em produção para validar como as partes se encaixam.

Ilustradora freelancer faz 10 anos. Viciada em Warcraft, aspirante a cosplayer e druida tanker no WoW.
Mamãe da Nulla-Chan e volta e meia lê scripts por pura pressão do Mortaro.

Experimentalista, escritor de universos, sonhador e desenvolvedor quando acha e toca a fita K7 sem título certa.
Usuário de features não documentadas e criador de issues exigindo documentação que ele mesmo vai fazer.

Instrutor da TipsCode. Desenvolvedor Full-stack JavaScript, apaixonado por tecnologia e servo do Senhor Jesus Cristo.
Encarregado da criação de conteúdo sobre o Nullstack, aulas, dicas e tutoriais. Com objetivo de tornar o Nullstack fácil de usar.
* A lista pode demorar um pouco para ser atualizada devido ao cache da API do GitHub
* A lista pode demorar um pouco para ser atualizada devido ao cache da API do GitHub
É simples. Encontrou um bug ou deseja um novo recurso?
Crie uma issue ou envie uma pull request com testes.
O Nullstack está sendo desenvolvido desde janeiro de 2019 com recursos sendo extraídos de projetos freelance.
Nesse ponto, a API está estável, os métodos de ciclo de vida e as chaves de contexto estarão praticamente congelados.
Ainda não estamos na v1.0, mas muito perto, a única coisa que falta é testá-lo em aplicativos feitos fora da equipe principal para descobrir se ele atende às necessidades de outros programadores.
As próximas atualizações serão direcionadas a correções de quaisquer bugs encontrados e terão foco na qualidade de vida.
As atualizações listadas nas issues do Nullstack são as próximas etapas planejadas sem nenhuma ordem específica.
O Nullstack foi desenvolvido por freelancers full-stacks neuroatípicos.
Com um histórico pesado em Rails, Ember.js, React.js e filosofia Vue.js as inspirações tiradas desses projetos podem ser óbvias.

Criador do conceito. Vai com novas propostas de API para seus patos de borracha favoritos e retorna com commits.
Fez a engenharia reversa de código de pensamento positivo para sua existência e depois o refatorou em um framework.

Pato de borracha com habilidades humanas, garante que o código não saia muito pra fora da caixa, então faz a caixa parecer legal.
Revisor de API que desenvolveu projetos de terceiros para testar a prova de conceitos de uma perspectiva focada no front-end.

Pato de borracha com um pescoço para encontrar inconsistências e problemas, esperando até que uma API seja aprovada para nos forçar a reescrever tudo.
Adotante antecipada do framework que desenvolveu aplicações reais em produção para validar como as partes se encaixam.

Ilustradora freelancer faz 10 anos. Viciada em Warcraft, aspirante a cosplayer e druida tanker no WoW.
Mamãe da Nulla-Chan e volta e meia lê scripts por pura pressão do Mortaro.

Experimentalista, escritor de universos, sonhador e desenvolvedor quando acha e toca a fita K7 sem título certa.
Usuário de features não documentadas e criador de issues exigindo documentação que ele mesmo vai fazer.

Instrutor da TipsCode. Desenvolvedor Full-stack JavaScript, apaixonado por tecnologia e servo do Senhor Jesus Cristo.
Encarregado da criação de conteúdo sobre o Nullstack, aulas, dicas e tutoriais. Com objetivo de tornar o Nullstack fácil de usar.
* A lista pode demorar um pouco para ser atualizada devido ao cache da API do GitHub
* A lista pode demorar um pouco para ser atualizada devido ao cache da API do GitHub
É simples. Encontrou um bug ou deseja um novo recurso?
Crie uma issue ou envie uma pull request com testes.
Siga esses passos e se torne um desenvolvedor full-stack javascript!
Comece sua jornada no Nullstack com estes conceitos básicos
Estes são conceitos que você provavelmente aprenderá conforme precisar em seus projetos
A melhor maneira de aprender Nullstack é lendo algum código
Siga esses passos e se torne um desenvolvedor full-stack javascript!
Comece sua jornada no Nullstack com estes conceitos básicos
Estes são conceitos que você provavelmente aprenderá conforme precisar em seus projetos
A melhor maneira de aprender Nullstack é lendo algum código
Usar estilos com o Nullstack é tão simples quanto importar um arquivo de estilo.
-O Nullstack vem com um loader SASS por padrão, mas você ainda pode usar o CSS Vanilla.
---✨ É uma boa prática importar um arquivo com o mesmo nome do componente.
-
import Nullstack from 'nullstack';
-import './Header.scss';
-
-class Header extends Nullstack {
- // ...
-}
-
-export default Header;
-
-No modo de produção, o Nullstack usa PurgeCSS, que limpa seu arquivo client.css, mas tem alguns truques.
---✨ Saiba mais sobre fazendo uma safelist do seu css
-
⚔ Aprenda sobre a extensão de arquivo NJS.
-Usar estilos com o Nullstack é tão simples quanto importar um arquivo de estilo.
-O Nullstack vem com um loader SASS por padrão, mas você ainda pode usar o CSS Vanilla.
---✨ É uma boa prática importar um arquivo com o mesmo nome do componente.
-
import Nullstack from 'nullstack';
-import './Header.scss';
-
-class Header extends Nullstack {
- // ...
-}
-
-export default Header;
-
-No modo de produção, o Nullstack usa PurgeCSS, que limpa seu arquivo client.css, mas tem alguns truques.
---✨ Saiba mais sobre fazendo uma safelist do seu css
-
⚔ Aprenda sobre a extensão de arquivo NJS.
-Usar estilos com o Nullstack é tão simples quanto importar um arquivo de estilo.
\nO Nullstack vem com um loader SASS por padrão, mas você ainda pode usar o CSS Vanilla.
\n\n\n✨ É uma boa prática importar um arquivo com o mesmo nome do componente.
\n
import Nullstack from 'nullstack';\nimport './Header.scss';\n\nclass Header extends Nullstack {\n // ...\n}\n\nexport default Header;\n\nNo modo de produção, o Nullstack usa PurgeCSS, que limpa seu arquivo client.css, mas tem alguns truques.
\n\n\n✨ Saiba mais sobre fazendo uma safelist do seu css
\n
⚔ Aprenda sobre a extensão de arquivo NJS.
\n","description":"Usar estilos com o Nullstack é tão simples quanto importar um arquivo de estilo."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Estilos - Nullstack","description":"Usar estilos com o Nullstack é tão simples quanto importar um arquivo de estilo."}} \ No newline at end of file diff --git a/docs/pt-br/extensao-de-arquivo-njs.html b/docs/pt-br/extensao-de-arquivo-njs.html deleted file mode 100644 index 580c014e..00000000 --- a/docs/pt-br/extensao-de-arquivo-njs.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - -Os arquivos do Nullstack permitem ao Webpack saber quais carregadores usar no momento da transpilação.
-Os arquivos NJS devem importar o Nullstack ou uma de suas subclasses.
-Se apenas uma subclasse for importada, uma importação Nullstack será injetada no momento da transpilação.
-No momento da transpilação, as tags JSX serão substituídas por Nullstack.element.
Essa extensão também permite que o Nullstack faça otimizações em tempo de transpilação, como a injeção de origem.
---🔥 Cada arquivo deve ter apenas uma classe declarada.
-
--🐱💻 Abaixo um exemplo de arquivo .njs original.
-
import List from './List';
-import {readFileSync} from 'fs';
-
-class Tasks extends List {
-
- static async getTasks({limit}) {
- const json = readFileSync('tasks.json', 'utf-8');
- return JSON.parse(json).tasks.slice(0, limit);
- }
-
- prepare(context) {
- context.tasks = [];
- }
-
- async initiate(context) {
- context.tasks = await this.getTasks({limit: 10});
- }
-
- renderTask({task}) {
- return (
- <li>
- <input bind={task.description} />
- </li>
- )
- }
-
- render() {
- return (
- <main>
- <ul>
- {tasks.map((task) => <Task task={task} />)}
- </ul>
- </main>
- )
- }
-
-}
-
-export default Tasks;
-
---🐱💻 Abaixo um exemplo do mesmo arquivo .njs transpilado.
-
import Nullstack from 'nullstack';
-import List from './List';
-
-class Tasks extends List {
-
- static hash = 'd493ac09d0d57574a30f136d31da455f';
-
- static getTasks = Nullstack.invoke('getTasks', 'd493ac09d0d57574a30f136d31da455f');
-
- prepare(context) {
- context.tasks = [];
- }
-
- async initiate(context) {
- context.tasks = await this.getTasks({limit: 10});
- }
-
- renderTask({task}) {
- return (
- <li>
- <input source={task} bind="description" />
- </li>
- )
- }
-
- render() {
- const Task = this.renderTask;
- return (
- <main>
- <ul>
- {tasks.map((task) => <Task task={task} />)}
- </ul>
- </main>
- )
- }
-
-}
-
-export default Tasks;
-
-⚔ Aprenda sobre a renderização no servidor.
-Os arquivos do Nullstack permitem ao Webpack saber quais carregadores usar no momento da transpilação.
-Os arquivos NJS devem importar o Nullstack ou uma de suas subclasses.
-Se apenas uma subclasse for importada, uma importação Nullstack será injetada no momento da transpilação.
-No momento da transpilação, as tags JSX serão substituídas por Nullstack.element.
Essa extensão também permite que o Nullstack faça otimizações em tempo de transpilação, como a injeção de origem.
---🔥 Cada arquivo deve ter apenas uma classe declarada.
-
--🐱💻 Abaixo um exemplo de arquivo .njs original.
-
import List from './List';
-import {readFileSync} from 'fs';
-
-class Tasks extends List {
-
- static async getTasks({limit}) {
- const json = readFileSync('tasks.json', 'utf-8');
- return JSON.parse(json).tasks.slice(0, limit);
- }
-
- prepare(context) {
- context.tasks = [];
- }
-
- async initiate(context) {
- context.tasks = await this.getTasks({limit: 10});
- }
-
- renderTask({task}) {
- return (
- <li>
- <input bind={task.description} />
- </li>
- )
- }
-
- render() {
- return (
- <main>
- <ul>
- {tasks.map((task) => <Task task={task} />)}
- </ul>
- </main>
- )
- }
-
-}
-
-export default Tasks;
-
---🐱💻 Abaixo um exemplo do mesmo arquivo .njs transpilado.
-
import Nullstack from 'nullstack';
-import List from './List';
-
-class Tasks extends List {
-
- static hash = 'd493ac09d0d57574a30f136d31da455f';
-
- static getTasks = Nullstack.invoke('getTasks', 'd493ac09d0d57574a30f136d31da455f');
-
- prepare(context) {
- context.tasks = [];
- }
-
- async initiate(context) {
- context.tasks = await this.getTasks({limit: 10});
- }
-
- renderTask({task}) {
- return (
- <li>
- <input source={task} bind="description" />
- </li>
- )
- }
-
- render() {
- const Task = this.renderTask;
- return (
- <main>
- <ul>
- {tasks.map((task) => <Task task={task} />)}
- </ul>
- </main>
- )
- }
-
-}
-
-export default Tasks;
-
-⚔ Aprenda sobre a renderização no servidor.
-Os arquivos do Nullstack permitem ao Webpack saber quais carregadores usar no momento da transpilação.
\nOs arquivos NJS devem importar o Nullstack ou uma de suas subclasses.
\nSe apenas uma subclasse for importada, uma importação Nullstack será injetada no momento da transpilação.
\nNo momento da transpilação, as tags JSX serão substituídas por Nullstack.element.
Essa extensão também permite que o Nullstack faça otimizações em tempo de transpilação, como a injeção de origem.
\n\n\n🔥 Cada arquivo deve ter apenas uma classe declarada.
\n
\n\n🐱💻 Abaixo um exemplo de arquivo .njs original.
\n
import List from './List';\nimport {readFileSync} from 'fs';\n\nclass Tasks extends List {\n\n static async getTasks({limit}) {\n const json = readFileSync('tasks.json', 'utf-8');\n return JSON.parse(json).tasks.slice(0, limit);\n }\n\n prepare(context) {\n context.tasks = [];\n }\n\n async initiate(context) {\n context.tasks = await this.getTasks({limit: 10});\n }\n\n renderTask({task}) {\n return (\n <li> \n <input bind={task.description} />\n </li>\n )\n }\n\n render() {\n return (\n <main>\n <ul>\n {tasks.map((task) => <Task task={task} />)}\n </ul>\n </main>\n )\n }\n\n}\n\nexport default Tasks;\n\n\n\n🐱💻 Abaixo um exemplo do mesmo arquivo .njs transpilado.
\n
import Nullstack from 'nullstack';\nimport List from './List';\n\nclass Tasks extends List {\n\n static hash = 'd493ac09d0d57574a30f136d31da455f';\n\n static getTasks = Nullstack.invoke('getTasks', 'd493ac09d0d57574a30f136d31da455f');\n\n prepare(context) {\n context.tasks = [];\n }\n\n async initiate(context) {\n context.tasks = await this.getTasks({limit: 10});\n }\n\n renderTask({task}) {\n return (\n <li> \n <input source={task} bind=\"description\" />\n </li>\n )\n }\n\n render() {\n const Task = this.renderTask;\n return (\n <main>\n <ul>\n {tasks.map((task) => <Task task={task} />)}\n </ul>\n </main>\n )\n }\n\n}\n\nexport default Tasks;\n\n⚔ Aprenda sobre a renderização no servidor.
\n","description":"Os arquivos Nullstack permitem que o Webpack saiba quais carregadores usar no momento da transpilação"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Extensão de arquivos NJS - Nullstack","description":"Os arquivos Nullstack permitem que o Webpack saiba quais carregadores usar no momento da transpilação"}} \ No newline at end of file diff --git "a/docs/pt-br/extens\303\243o-de-arquivo-njs.html" "b/docs/pt-br/extens\303\243o-de-arquivo-njs.html" deleted file mode 100644 index c29ce87e..00000000 --- "a/docs/pt-br/extens\303\243o-de-arquivo-njs.html" +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Talvez você queira aprender como criar uma pagina 404 com Nullstack?
-Se você está procurando por outra coisa, você deveria ler a documentação.
-Talvez você queira aprender como criar uma pagina 404 com Nullstack?
-Se você está procurando por outra coisa, você deveria ler a documentação.
-Talvez você queira aprender como criar uma pagina 404 com Nullstack?
\nSe você está procurando por outra coisa, você deveria ler a documentação.
\n","description":"Desculpe, essa não é a página que você está procurando","status":404},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":404,"title":"Página Não Encontrada - Nullstack","description":"Desculpe, essa não é a página que você está procurando"}} \ No newline at end of file diff --git a/docs/pt-br/funcoes-de-servidor.html b/docs/pt-br/funcoes-de-servidor.html deleted file mode 100644 index e2bee2d1..00000000 --- a/docs/pt-br/funcoes-de-servidor.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - -Server functions are specialized microservices that at transpile time are converted into API entry points.
-To flag a function as a server function, you must declare it as static async.
Being a static function means it has no access to the instance scope.
-However, instead of calling the static version from the class, you must invoke it as an instance function.
-Server functions can be called anytime in your code and are not limited to prerender steps.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async increment(context) {
- context.count++;
- }
-
- async handleClick() {
- await this.increment();
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Learn more about the server context.
-
When you call a server function from the client, the arguments will be serialized as JSON.
-The arguments will be posted against the automatically generated API and merged with the server context when it reaches the server.
-The return value of the server function will be serialized back to the client and can be seamlessly used as if it were a local function.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async increment(context) {
- context.count++;
- return context.count;
- }
-
- async handleClick() {
- this.count = await this.increment();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Server functions will be used as local functions, simply aliasing the instance call to the class and merging the arguments with the server context.
-Dates are serialized as UTC in JSON and deserialized back to Date objects.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- async initiate() {
- const date = new Date();
- const verified = this.verifyDay({date});
- }
-
- static async verifyDay({date}) {
- return date.getDay() === new Date().getDay();
- }
-
- // ...
-
-}
-
-export default Component;
-
-fetch is available in both server and client functions for the sake of isomorphy.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async initiate() {
- const url = 'https://api.github.com/repos/nullstack/nullstack/issues';
- const response = await fetch(url);
- this.issues = await response.json();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Imported dependencies that are only used inside server functions will be excluded from the client bundle.
-This is useful for both accessing node.js exclusive modules and reducing the client bundle size by preprocessing data like markdown without having to expose the dependency to the end-user.
-import Nullstack from 'nullstack';
-import {readFileSync} from 'fs';
-import {Remarkable} from 'remarkable';
-
-class Application extends Nullstack {
-
- static async getTasks() {
- const readme = readFileSync('README.md', 'utf-8');
- return new Remarkable().render(readme);
- }
-
- // ...
-
-}
-
-export default Application;
-
-Keep in mind that every server function is similar to an Express route in API and must be coded without depending on view logic for security.
---🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
-
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async getCount({request, count}) {
- if(!request.session.user) return 0;
- return count;
- }
-
- // ...
-
-}
-
-export default Component;
-
---💡 Server functions are not exposed to the client.
-
--✨ Learn more about the NJS file extension.
-
Server function names cannot collide with instance method names from the current class or its parent classes.
-The following words cannot be used in server functions:
-prepareinitiatehydrateupdateterminateServer functions named start will not generate an API endpoint and can only be called by other server functions.
Automatically generated API endpoints are not meant to be used by 3rd-party apps.
-The URL and implementation may change between versions of Nullstack.
---✨ If you want to build an API, learn more about how to create an API with Nullstack.
-
⚔ Learn about the context.
-Server functions are specialized microservices that at transpile time are converted into API entry points.
-To flag a function as a server function, you must declare it as static async.
Being a static function means it has no access to the instance scope.
-However, instead of calling the static version from the class, you must invoke it as an instance function.
-Server functions can be called anytime in your code and are not limited to prerender steps.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async increment(context) {
- context.count++;
- }
-
- async handleClick() {
- await this.increment();
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Learn more about the server context.
-
When you call a server function from the client, the arguments will be serialized as JSON.
-The arguments will be posted against the automatically generated API and merged with the server context when it reaches the server.
-The return value of the server function will be serialized back to the client and can be seamlessly used as if it were a local function.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async increment(context) {
- context.count++;
- return context.count;
- }
-
- async handleClick() {
- this.count = await this.increment();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Server functions will be used as local functions, simply aliasing the instance call to the class and merging the arguments with the server context.
-Dates are serialized as UTC in JSON and deserialized back to Date objects.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- async initiate() {
- const date = new Date();
- const verified = this.verifyDay({date});
- }
-
- static async verifyDay({date}) {
- return date.getDay() === new Date().getDay();
- }
-
- // ...
-
-}
-
-export default Component;
-
-fetch is available in both server and client functions for the sake of isomorphy.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async initiate() {
- const url = 'https://api.github.com/repos/nullstack/nullstack/issues';
- const response = await fetch(url);
- this.issues = await response.json();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Imported dependencies that are only used inside server functions will be excluded from the client bundle.
-This is useful for both accessing node.js exclusive modules and reducing the client bundle size by preprocessing data like markdown without having to expose the dependency to the end-user.
-import Nullstack from 'nullstack';
-import {readFileSync} from 'fs';
-import {Remarkable} from 'remarkable';
-
-class Application extends Nullstack {
-
- static async getTasks() {
- const readme = readFileSync('README.md', 'utf-8');
- return new Remarkable().render(readme);
- }
-
- // ...
-
-}
-
-export default Application;
-
-Keep in mind that every server function is similar to an Express route in API and must be coded without depending on view logic for security.
---🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
-
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async getCount({request, count}) {
- if(!request.session.user) return 0;
- return count;
- }
-
- // ...
-
-}
-
-export default Component;
-
---💡 Server functions are not exposed to the client.
-
--✨ Learn more about the NJS file extension.
-
Server function names cannot collide with instance method names from the current class or its parent classes.
-The following words cannot be used in server functions:
-prepareinitiatehydrateupdateterminateServer functions named start will not generate an API endpoint and can only be called by other server functions.
Automatically generated API endpoints are not meant to be used by 3rd-party apps.
-The URL and implementation may change between versions of Nullstack.
---✨ If you want to build an API, learn more about how to create an API with Nullstack.
-
⚔ Learn about the context.
-Server functions are specialized microservices that at transpile time are converted into API entry points.
\nTo flag a function as a server function, you must declare it as static async.
Being a static function means it has no access to the instance scope.
\nHowever, instead of calling the static version from the class, you must invoke it as an instance function.
\nServer functions can be called anytime in your code and are not limited to prerender steps.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n static async increment(context) {\n context.count++;\n }\n\n async handleClick() {\n await this.increment();\n }\n\n // ...\n\n}\n\nexport default Component;\n\n\n\n✨ Learn more about the server context.
\n
When you call a server function from the client, the arguments will be serialized as JSON.
\nThe arguments will be posted against the automatically generated API and merged with the server context when it reaches the server.
\nThe return value of the server function will be serialized back to the client and can be seamlessly used as if it were a local function.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n static async increment(context) {\n context.count++;\n return context.count;\n }\n\n async handleClick() {\n this.count = await this.increment();\n }\n\n // ...\n\n}\n\nexport default Component;\n\nServer functions will be used as local functions, simply aliasing the instance call to the class and merging the arguments with the server context.
\nDates are serialized as UTC in JSON and deserialized back to Date objects.
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n async initiate() {\n const date = new Date();\n const verified = this.verifyDay({date});\n }\n\n static async verifyDay({date}) {\n return date.getDay() === new Date().getDay();\n }\n\n // ...\n\n}\n\nexport default Component;\n\nfetch is available in both server and client functions for the sake of isomorphy.
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async initiate() {\n const url = 'https://api.github.com/repos/nullstack/nullstack/issues';\n const response = await fetch(url);\n this.issues = await response.json();\n }\n\n // ...\n\n}\n\nexport default Component;\n\nImported dependencies that are only used inside server functions will be excluded from the client bundle.
\nThis is useful for both accessing node.js exclusive modules and reducing the client bundle size by preprocessing data like markdown without having to expose the dependency to the end-user.
\nimport Nullstack from 'nullstack';\nimport {readFileSync} from 'fs';\nimport {Remarkable} from 'remarkable';\n\nclass Application extends Nullstack {\n\n static async getTasks() {\n const readme = readFileSync('README.md', 'utf-8');\n return new Remarkable().render(readme);\n }\n\n // ...\n\n}\n\nexport default Application;\n\nKeep in mind that every server function is similar to an Express route in API and must be coded without depending on view logic for security.
\n\n\n🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
\n
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n static async getCount({request, count}) {\n if(!request.session.user) return 0;\n return count;\n }\n\n // ...\n\n}\n\nexport default Component;\n\n\n\n💡 Server functions are not exposed to the client.
\n
\n\n✨ Learn more about the NJS file extension.
\n
Server function names cannot collide with instance method names from the current class or its parent classes.
\nThe following words cannot be used in server functions:
\nprepareinitiatehydrateupdateterminateServer functions named start will not generate an API endpoint and can only be called by other server functions.
Automatically generated API endpoints are not meant to be used by 3rd-party apps.
\nThe URL and implementation may change between versions of Nullstack.
\n\n\n✨ If you want to build an API, learn more about how to create an API with Nullstack.
\n
⚔ Learn about the context.
\n","description":"Server functions are specialized microservices that at transpile time are converted into API entry points"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Server Functions - Nullstack","description":"Server functions are specialized microservices that at transpile time are converted into API entry points"}} \ No newline at end of file diff --git a/docs/pt-br/geracao-de-sites-estaticos.html b/docs/pt-br/geracao-de-sites-estaticos.html deleted file mode 100644 index a0b7441c..00000000 --- a/docs/pt-br/geracao-de-sites-estaticos.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - -Use Nullstack para gerar websites estáticos para aplicações estáticas ultrarrápidas usando todo o potencial do cliente Nullstack sem a necessidade de haver um back-end de node.js.
-Websites estáticos são úteis para aplicações read-only como blogs e documentação
---💡 Esta documentação é na verdade um site estático gerado com Nullstack
-
Todos os benefícios de renderização no lado do servidor se aplicam para websites gerados estáticamente.
-Você pode gerar um website estático a partir da sua aplicação Nullstack com o seguinte comando npx:
npx create-nullstatic-app
-
---🔥 Você deve estar em uma pasta de projeto Nullstack para executar esse comando.
-
Por padrão, a sua aplicação Nullstack será criada na pasta static.
-Você pode mudar a pasta padrão por passá-la para o comando como um argumento:
-npx create-nullstatic-app docs
-
-O Nullstatic generator irá executar a sua aplicação no modo produção e irá rastrear cada link para uma rota interna que encontrar no seu DOM.
---💡 Certifique-se que a porta de produção do servidor se encontra livre quando executar esse comando.
-
O manifest.json e o conteúdo da pasta pública serão copiados para a pasta de destino.
-Além de gerar raw HTML também irá gerar um arquivo JSON para cada rota com uma cópia do estado.
-Na primeira visita para a sua aplicação estática, HTML será veiculado e hidratado.
-Nos pedidos subsequentes, Nullstack irá buscar o JSON gerado e atualizar o estado da aplicação sem que haja a necessidade de recarregar a página.
-Isso, na verdade, oferece não apenas um site estático gerado, mas um API gerado estaticamente que alimenta a Single Page Application sem nenhum custo.
-Você pode adicionar um script para a sua package.json a fim de gerar o seu website estático em uma pasta personalizada:
-{
- "name": "nullstack.github.io",
- "version": "0.0.1",
- "description": "",
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "nullstack": "~0.9.0"
- },
- "scripts": {
- "start": "npx webpack --config node_modules/nullstack/webpack.config.js --mode=development --watch",
- "build": "npx webpack --config node_modules/nullstack/webpack.config.js --mode=production",
- "ssg": "npx create-nullstatic-app docs"
- }
-}
-
-
-Nullstatic rastreia a sua aplicação apenas até a resolução de initiate, outras solicitações de API acionadas por eventos serão ignoradas.
Nullstatic rastreará um URL "/404" e gerará um "/404.html" e um "/404/index.html".
-⚔ Aprenda mais sobre o trabalhador de serviço.
-Use Nullstack para gerar websites estáticos para aplicações estáticas ultrarrápidas usando todo o potencial do cliente Nullstack sem a necessidade de haver um back-end de node.js.
-Websites estáticos são úteis para aplicações read-only como blogs e documentação
---💡 Esta documentação é na verdade um site estático gerado com Nullstack
-
Todos os benefícios de renderização no lado do servidor se aplicam para websites gerados estáticamente.
-Você pode gerar um website estático a partir da sua aplicação Nullstack com o seguinte comando npx:
npx create-nullstatic-app
-
---🔥 Você deve estar em uma pasta de projeto Nullstack para executar esse comando.
-
Por padrão, a sua aplicação Nullstack será criada na pasta static.
-Você pode mudar a pasta padrão por passá-la para o comando como um argumento:
-npx create-nullstatic-app docs
-
-O Nullstatic generator irá executar a sua aplicação no modo produção e irá rastrear cada link para uma rota interna que encontrar no seu DOM.
---💡 Certifique-se que a porta de produção do servidor se encontra livre quando executar esse comando.
-
O manifest.json e o conteúdo da pasta pública serão copiados para a pasta de destino.
-Além de gerar raw HTML também irá gerar um arquivo JSON para cada rota com uma cópia do estado.
-Na primeira visita para a sua aplicação estática, HTML será veiculado e hidratado.
-Nos pedidos subsequentes, Nullstack irá buscar o JSON gerado e atualizar o estado da aplicação sem que haja a necessidade de recarregar a página.
-Isso, na verdade, oferece não apenas um site estático gerado, mas um API gerado estaticamente que alimenta a Single Page Application sem nenhum custo.
-Você pode adicionar um script para a sua package.json a fim de gerar o seu website estático em uma pasta personalizada:
-{
- "name": "nullstack.github.io",
- "version": "0.0.1",
- "description": "",
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "nullstack": "~0.9.0"
- },
- "scripts": {
- "start": "npx webpack --config node_modules/nullstack/webpack.config.js --mode=development --watch",
- "build": "npx webpack --config node_modules/nullstack/webpack.config.js --mode=production",
- "ssg": "npx create-nullstatic-app docs"
- }
-}
-
-
-Nullstatic rastreia a sua aplicação apenas até a resolução de initiate, outras solicitações de API acionadas por eventos serão ignoradas.
Nullstatic rastreará um URL "/404" e gerará um "/404.html" e um "/404/index.html".
-⚔ Aprenda mais sobre o trabalhador de serviço.
-Use Nullstack para gerar websites estáticos para aplicações estáticas ultrarrápidas usando todo o potencial do cliente Nullstack sem a necessidade de haver um back-end de node.js.
\nWebsites estáticos são úteis para aplicações read-only como blogs e documentação
\n\n\n💡 Esta documentação é na verdade um site estático gerado com Nullstack
\n
Todos os benefícios de renderização no lado do servidor se aplicam para websites gerados estáticamente.
\nVocê pode gerar um website estático a partir da sua aplicação Nullstack com o seguinte comando npx:
npx create-nullstatic-app\n\n\n\n🔥 Você deve estar em uma pasta de projeto Nullstack para executar esse comando.
\n
Por padrão, a sua aplicação Nullstack será criada na pasta static.
\nVocê pode mudar a pasta padrão por passá-la para o comando como um argumento:
\nnpx create-nullstatic-app docs\n\nO Nullstatic generator irá executar a sua aplicação no modo produção e irá rastrear cada link para uma rota interna que encontrar no seu DOM.
\n\n\n💡 Certifique-se que a porta de produção do servidor se encontra livre quando executar esse comando.
\n
O manifest.json e o conteúdo da pasta pública serão copiados para a pasta de destino.
\nAlém de gerar raw HTML também irá gerar um arquivo JSON para cada rota com uma cópia do estado.
\nNa primeira visita para a sua aplicação estática, HTML será veiculado e hidratado.
\nNos pedidos subsequentes, Nullstack irá buscar o JSON gerado e atualizar o estado da aplicação sem que haja a necessidade de recarregar a página.
\nIsso, na verdade, oferece não apenas um site estático gerado, mas um API gerado estaticamente que alimenta a Single Page Application sem nenhum custo.
\nVocê pode adicionar um script para a sua package.json a fim de gerar o seu website estático em uma pasta personalizada:
\n{\n \"name\": \"nullstack.github.io\",\n \"version\": \"0.0.1\",\n \"description\": \"\",\n \"author\": \"\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"nullstack\": \"~0.9.0\"\n },\n \"scripts\": {\n \"start\": \"npx webpack --config node_modules/nullstack/webpack.config.js --mode=development --watch\",\n \"build\": \"npx webpack --config node_modules/nullstack/webpack.config.js --mode=production\",\n \"ssg\": \"npx create-nullstatic-app docs\"\n }\n}\n\n\nNullstatic rastreia a sua aplicação apenas até a resolução de initiate, outras solicitações de API acionadas por eventos serão ignoradas.
Nullstatic rastreará um URL "/404" e gerará um "/404.html" e um "/404/index.html".
\n⚔ Aprenda mais sobre o trabalhador de serviço.
\n","título":"Geração de Site Estático","descrição":"Use Nullstack para gerar websites estáticos para aplicações estáticas ultrarrápidas usando todo o potencial de Nullstack sem a necessidade de ter um back-end de node.js"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"undefined - Nullstack"}} \ No newline at end of file diff --git a/docs/pt-br/index.html b/docs/pt-br/index.html deleted file mode 100644 index af0b34af..00000000 --- a/docs/pt-br/index.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - -para exércitos de um dev só
Nullstack é um framework full-stack para construir aplicações web progressivas.
Ele conecta uma camada de UI com estado a microserviços especializados no mesmo componente usando vanilla javascript.
Concentre-se em resolver sua lógica de negócios em vez de escrever código para interoperabilidade.
Nullstack gera HTML otimizado e com SEO pronto para o primeiro rascunho de sua rota em uma única requisição usando funções locais e com zero dependências javascript no cliente.
Após hidratação, requisições irão buscar JSON de uma API gerada automaticamente por funções do servidor, atualizar o estado da aplicação e renderizar a página novamente.
Você pode até usar o Nullstack para gerar sites estáticos ultra-rápidos que servem HTML e se tornam uma Single Page Application usando uma API estática gerada automaticamente.
Nullstack não é apenas outra parte de sua stack, mas sim a sua stack
Sua aplicação pode ser exportado do back-end para o front-end como um componente e montado em outra aplicação
import Nullstack from 'nullstack';
-
-class ProductList extends Nullstack {
-
- products = [];
-
- static async getProducts({ database }) {
- const [products] = await database.query(
- 'SELECT * FROM products'
- );
- return products;
- }
-
- async initiate() {
- this.products = await this.getProducts();
- }
-
- static async deleteProduct({ database, id }) {
- await database.query(
- 'DELETE FROM products WHERE id=?',
- [id]
- );
- }
-
- async remove({ id }) {
- await this.deleteProduct({ id });
- await this.initiate();
- }
-
- renderProduct({ id, name }) {
- return (
- <li>
- <button onclick={this.remove} id={id}>
- {name}
- </button>
- </li>
- )
- }
-
- render() {
- return (
- <ul>
- {this.products.map((product) => (
- <Product {...product} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default ProductList;import Nullstack from 'nullstack';
-
-class ProductForm extends Nullstack {
-
- name = '';
- price = 0;
-
- static async getProductById({ database, id }) {
- const [products] = await database.query(
- 'SELECT * FROM products WHERE id=? LIMIT 1',
- [id]
- );
- return products[0];
- }
-
- async initiate({ params }) {
- const product = await this.getProductById({
- id: params.id
- });
- this.name = product.name;
- this.price = product.price;
- }
-
- static async updateProduct({ database, name, price, id }) {
- await database.query(
- 'UPDATE products SET name=?, price=? WHERE id=?',
- [name, price, id]
- );
- }
-
- async submit({ router, params }) {
- await this.updateProduct({
- id: params.id,
- name: this.name,
- price: this.price
- });
- router.url = '/products';
- }
-
- render() {
- return (
- <form onsubmit={this.submit}>
- <input class="form-control" bind={this.name} />
- <input type="number" step=".01" bind={this.price} />
- <button>Submit</button>
- </form>
- )
- }
-
-}
-
-export default ProductForm;O exemplo acima é o código completo de uma listagem de produtos e um formulário de edição sem esconder nenhuma linha.
Ambos os componentes invocam funções de servidor para ter acesso ao banco de dados MySQL no meio do JavaScript sem você ter que pensar em APIs.
Os recursos do Nullstack foram extraídos de projetos da vida real com conveniência e consistência em mente
import Nullstack from 'nullstack';
-
-class Controlled extends Nullstack {
-
- count = 0;
-
- increment({delta}) {
- this.count += delta;
- }
-
- render() {
- return (
- <div>
- <button onclick={this.increment} delta={-1}>
- {this.count}
- </button>
- <span> {this.count} </span>
- <button onclick={this.increment} delta={1}>
- {this.count}
- </button>
- </div>
- )
- }
-
-}
-
-export default Controlled;import Nullstack from 'nullstack';
-
-class Binding extends Nullstack {
-
- number = 1;
- boolean = true;
-
- object = {number: 1};
- array = ['a', 'b', 'c'];
-
- render({params}) {
- return (
- <form>
- <input bind={this.number} />
- <input bind={this.boolean} type="checkbox" />
- <input bind={this.object.number} />
- {this.array.map((value, index) => (
- <input bind={this.array[index]} />
- ))}
- <input bind={params.page} />
- </form>
- )
- }
-
-}
-
-export default Binding;import Nullstack from 'nullstack';
-
-class Routes extends Nullstack {
-
- renderPost({params}) {
- return (
- <div>
- <div route="/post/getting-started">
- npx create-nullstack-app name
- </div>
- <div route="*"> {params.slug} </div>
- </div>
- )
- }
-
- render() {
- return (
- <div>
- <Post route="/post/:slug" />
- <a href="/post/hello-world"> Welcome </a>
- </div>
- )
- }
-
-}
-
-export default Routes;import Nullstack from 'nullstack';
-
-class Lifecycle extends Nullstack {
-
- prepare({environment}) {
- const {server, client} = environment;
- }
-
- async initiate({environment}) {
- const {server, client} = environment;
- }
-
- async hydrate({environment}) {
- const {client} = environment;
- }
-
- async update({environment}) {
- const {client} = environment;
- }
-
- async terminate({environment}) {
- const {client} = environment;
- }
-
-}
-
-export default Lifecycle;Nullstack se preocupa em tornar seu conteúdo o mais direto ao ponto e fácil de entender quanto possível
Cada projeto começa pequeno e se torna complexo com o tempo. Escale conforme avança, não importa o tamanho da equipe.
Sem compromissos, sem imposições.Desenvolvimento de back e front end de um recurso no mesmo componente de forma organizada com facilidade de visão geral.
Verdadeira componentização e reutilização de código.Tira proveito de todo e qualquer pacote isomórfico em Vanilla Javascript já feito em toda história.
Todo o sua aplicação fala a mesma língua.A estrutura horizontal, ao contrário de uma hierárquica, torna muito mais fácil mover os recursos.
Flexibilidade acima de burocracia.O arquivo index.js na raiz da aplicação é responsável por iniciar a aplicação.
-Quando você executa a aplicação com npm start ou node .production/server.js, o index chama a função start em seu src/Application.js.
A função start será executada apenas uma vez quando sua aplicação for inicializada e é um bom lugar para configurar seu contexto de servidor.
import Nullstack from 'nullstack';
-import database from './database';
-
-class Application extends Nullstack {
-
- static async start(context) {
- context.database = database;
- }
-
-}
-
-export default Application;
-
-Um bom padrão para trabalhar com dependências que requerem configurações em tempo de inicialização é definir uma função start na dependência e chamá-la na função start da aplicação passando o contexto do servidor.
import Nullstack from 'nullstack';
-import Dependency from './Dependency';
-
-class Application extends Nullstack {
-
- static async start(context) {
- Dependency.start(context);
- }
-
-}
-
-export default Application;
-
---🔒 As funções de servidor com o nome começando com "start" (e opcionalmente seguido por uma letra maiúscula) não geram um endpoint de API para evitar inundação de contexto malicioso.
-
⚔ Aprenda sobre a chave data do contexto.
O arquivo index.js na raiz da aplicação é responsável por iniciar a aplicação.
-Quando você executa a aplicação com npm start ou node .production/server.js, o index chama a função start em seu src/Application.js.
A função start será executada apenas uma vez quando sua aplicação for inicializada e é um bom lugar para configurar seu contexto de servidor.
import Nullstack from 'nullstack';
-import database from './database';
-
-class Application extends Nullstack {
-
- static async start(context) {
- context.database = database;
- }
-
-}
-
-export default Application;
-
-Um bom padrão para trabalhar com dependências que requerem configurações em tempo de inicialização é definir uma função start na dependência e chamá-la na função start da aplicação passando o contexto do servidor.
import Nullstack from 'nullstack';
-import Dependency from './Dependency';
-
-class Application extends Nullstack {
-
- static async start(context) {
- Dependency.start(context);
- }
-
-}
-
-export default Application;
-
---🔒 As funções de servidor com o nome começando com "start" (e opcionalmente seguido por uma letra maiúscula) não geram um endpoint de API para evitar inundação de contexto malicioso.
-
⚔ Aprenda sobre a chave data do contexto.
O arquivo index.js na raiz da aplicação é responsável por iniciar a aplicação.
\nQuando você executa a aplicação com npm start ou node .production/server.js, o index chama a função start em seu src/Application.js.
A função start será executada apenas uma vez quando sua aplicação for inicializada e é um bom lugar para configurar seu contexto de servidor.
import Nullstack from 'nullstack';\nimport database from './database';\n\nclass Application extends Nullstack {\n\n static async start(context) {\n context.database = database;\n }\n\n}\n\nexport default Application;\n\nUm bom padrão para trabalhar com dependências que requerem configurações em tempo de inicialização é definir uma função start na dependência e chamá-la na função start da aplicação passando o contexto do servidor.
import Nullstack from 'nullstack';\nimport Dependency from './Dependency';\n\nclass Application extends Nullstack {\n\n static async start(context) {\n Dependency.start(context);\n }\n\n}\n\nexport default Application;\n\n\n\n🔒 As funções de servidor com o nome começando com "start" (e opcionalmente seguido por uma letra maiúscula) não geram um endpoint de API para evitar inundação de contexto malicioso.
\n
⚔ Aprenda sobre a chave data do contexto.
objectEle te dá informações sobre o ciclo de vida da instância e sua key única.
Cada instância recebe seu própio objeto self.
As seguintes keys estão disponíveis no objeto:
-booleanbooleanbooleanHTMLElementkey: stringQuando um método do ciclo de vida é resolvido, mesmo que não declarado, uma chave equivalente é setada para true no self.
Se o componente tiver sido renderizado no lado do servidor a chave prerendered continuará como true até que seja finalizado.
A chave element aponta para o seletor na DOM e sua existência só é garantida quando o hydrate está sendo chamado, pois prepare e initiate podem estar rodando no servidor.
--💡 Não use a chave
-elementpara adivinhar o ambiente, ao invés useenvironmentpara isso.
Observar o self é um bom jeito de evitar dar informações irrelevantes para o usuário final
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- // ...
-
- async initiate() {
- this.price = await this.getPrice();
- }
-
- async hydrate({self}) {
- self.element.querySelector('input').focus();
- }
-
- render({self}) {
- if(!self.prerendered && !self.initiated) return false;
- return (
- <form>
- <input type="number" bind={this.price} />
- <button disabled={!self.hydrated}>
- Save
- </button>
- </form>
- )
- }
-
-}
-
-export default Page;
-
---💡 Componentes que estão otimizados em functional components não tem acesso ao
-self.
stringEle permite que você persista a instância quando é movida no DOM.
-Você pode declarar uma key por instância.
--💡 Se você não declarar a
-keyo nullstack irá gerar uma baseada na profundidade da dom.
--🔥 As keys não podem começar com "_." para evitar conflito com as keys geradas pelo Nullstack
-
As keys devem ser globalmente únicas já que o componente poderá ser movido para qualquer lugar da DOM e não apenas entre os componentes irmãos.
-As keys são úteis para preservar o estado em componentes com estado quando você os move para dentro da DOM.
-Isto é especialmente útil para listas com tamanho dinâmico que invocam os componentes.
-import Nullstack from 'nullstack';
-import Item from './Item';
-
-class List extends Nullstack {
-
- // ...
-
- async initiate() {
- this.items = await this.getItems();
- }
-
- render({self}) {
- const componentKey = self.key;
- return (
- <ul>
- {this.items.map((item) => (
- <Item key={`${componentKey}-${item.id}`} {...item} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default Page;
-
-Você também pode usar as keys para compartilhar a instância entre dois elementos.
-Apenas o primeiro encontro da key irá executar o lifecycle.
import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render({amount}) {
- return (
- <div>
- <button onclick={{count: this.count+1}}>
- {this.count} x {amount} = {this.count * amount}
- </button>
- </div>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- render() {
- return (
- <main>
- <Counter key="a" amount={1} />
- <Counter key="b" amount={2} />
- <Counter key="b" amount={3} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-stringEle permite que você persista a instância quando é movida no DOM.
-Você pode declarar uma key por instância.
---💡 Se você não declarar a key o nullstack irá gerar uma baseada na profundidade da dom
-
--🔥 As keys não podem começar com "_." para evitar conflito com as keys geradas pelo Nullstack
-
As keys devem ser globalmente únicas já que o componente poderá ser movido para qualquer lugar da DOM e não apenas entre os componentes irmãos.
-As keys são úteis para preservar o estado em componentes com estado quando você os move para dentro da DOM.
-Isto é especialmente útil para listas com tamanho dinâmico que invocam os componentes.
-import Nullstack from 'nullstack';
-import Item from './Item';
-
-class List extends Nullstack {
-
- // ...
-
- async initiate() {
- this.items = await this.getItems();
- }
-
- render({self}) {
- const componentKey = self.key;
- return (
- <ul>
- {this.items.map((item) => (
- <Item key={`${componentKey}-${item.id}`} {...item} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default Page;
-
-Você também pode usar as keys para compartilhar a instância entre dois elementos.
-Apenas o primeiro encontro da key irá executar o lifecycle
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render({amount}) {
- return (
- <div>
- <button onclick={{count: this.count+1}}>
- {this.count} x {amount} = {this.count * amount}
- </button>
- </div>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- render() {
- return (
- <main>
- <Counter key="a" amount={1} />
- <Counter key="b" amount={2} />
- <Counter key="b" amount={3} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-⚔ Aprenda sobre requisicao e resposta do servidor.
-objectEle te dá informações sobre o ciclo de vida da instância e sua key única.
Cada instância recebe seu própio objeto self.
As seguintes keys estão disponíveis no objeto:
-booleanbooleanbooleanHTMLElementkey: stringQuando um método do ciclo de vida é resolvido, mesmo que não declarado, uma chave equivalente é setada para true no self.
Se o componente tiver sido renderizado no lado do servidor a chave prerendered continuará como true até que seja finalizado.
A chave element aponta para o seletor na DOM e sua existência só é garantida quando o hydrate está sendo chamado, pois prepare e initiate podem estar rodando no servidor.
--💡 Não use a chave
-elementpara adivinhar o ambiente, ao invés useenvironmentpara isso.
Observar o self é um bom jeito de evitar dar informações irrelevantes para o usuário final
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- // ...
-
- async initiate() {
- this.price = await this.getPrice();
- }
-
- async hydrate({self}) {
- self.element.querySelector('input').focus();
- }
-
- render({self}) {
- if(!self.prerendered && !self.initiated) return false;
- return (
- <form>
- <input type="number" bind={this.price} />
- <button disabled={!self.hydrated}>
- Save
- </button>
- </form>
- )
- }
-
-}
-
-export default Page;
-
---💡 Componentes que estão otimizados em functional components não tem acesso ao
-self.
stringEle permite que você persista a instância quando é movida no DOM.
-Você pode declarar uma key por instância.
--💡 Se você não declarar a
-keyo nullstack irá gerar uma baseada na profundidade da dom.
--🔥 As keys não podem começar com "_." para evitar conflito com as keys geradas pelo Nullstack
-
As keys devem ser globalmente únicas já que o componente poderá ser movido para qualquer lugar da DOM e não apenas entre os componentes irmãos.
-As keys são úteis para preservar o estado em componentes com estado quando você os move para dentro da DOM.
-Isto é especialmente útil para listas com tamanho dinâmico que invocam os componentes.
-import Nullstack from 'nullstack';
-import Item from './Item';
-
-class List extends Nullstack {
-
- // ...
-
- async initiate() {
- this.items = await this.getItems();
- }
-
- render({self}) {
- const componentKey = self.key;
- return (
- <ul>
- {this.items.map((item) => (
- <Item key={`${componentKey}-${item.id}`} {...item} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default Page;
-
-Você também pode usar as keys para compartilhar a instância entre dois elementos.
-Apenas o primeiro encontro da key irá executar o lifecycle.
import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render({amount}) {
- return (
- <div>
- <button onclick={{count: this.count+1}}>
- {this.count} x {amount} = {this.count * amount}
- </button>
- </div>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- render() {
- return (
- <main>
- <Counter key="a" amount={1} />
- <Counter key="b" amount={2} />
- <Counter key="b" amount={3} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-stringEle permite que você persista a instância quando é movida no DOM.
-Você pode declarar uma key por instância.
---💡 Se você não declarar a key o nullstack irá gerar uma baseada na profundidade da dom
-
--🔥 As keys não podem começar com "_." para evitar conflito com as keys geradas pelo Nullstack
-
As keys devem ser globalmente únicas já que o componente poderá ser movido para qualquer lugar da DOM e não apenas entre os componentes irmãos.
-As keys são úteis para preservar o estado em componentes com estado quando você os move para dentro da DOM.
-Isto é especialmente útil para listas com tamanho dinâmico que invocam os componentes.
-import Nullstack from 'nullstack';
-import Item from './Item';
-
-class List extends Nullstack {
-
- // ...
-
- async initiate() {
- this.items = await this.getItems();
- }
-
- render({self}) {
- const componentKey = self.key;
- return (
- <ul>
- {this.items.map((item) => (
- <Item key={`${componentKey}-${item.id}`} {...item} />
- ))}
- </ul>
- )
- }
-
-}
-
-export default Page;
-
-Você também pode usar as keys para compartilhar a instância entre dois elementos.
-Apenas o primeiro encontro da key irá executar o lifecycle
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render({amount}) {
- return (
- <div>
- <button onclick={{count: this.count+1}}>
- {this.count} x {amount} = {this.count * amount}
- </button>
- </div>
- )
- }
-
-}
-
-export default Counter;
-
-import Nullstack from 'nullstack';
-import Counter from './Counter';
-
-class Application extends Nullstack {
-
- render() {
- return (
- <main>
- <Counter key="a" amount={1} />
- <Counter key="b" amount={2} />
- <Counter key="b" amount={3} />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-⚔ Aprenda sobre requisicao e resposta do servidor.
-objectEle te dá informações sobre o ciclo de vida da instância e sua key única.
Cada instância recebe seu própio objeto self.
As seguintes keys estão disponíveis no objeto:
\nbooleanbooleanbooleanHTMLElementkey: stringQuando um método do ciclo de vida é resolvido, mesmo que não declarado, uma chave equivalente é setada para true no self.
Se o componente tiver sido renderizado no lado do servidor a chave prerendered continuará como true até que seja finalizado.
A chave element aponta para o seletor na DOM e sua existência só é garantida quando o hydrate está sendo chamado, pois prepare e initiate podem estar rodando no servidor.
\n\n💡 Não use a chave
\nelementpara adivinhar o ambiente, ao invés useenvironmentpara isso.
Observar o self é um bom jeito de evitar dar informações irrelevantes para o usuário final
import Nullstack from 'nullstack';\n\nclass Page extends Nullstack {\n\n // ...\n\n async initiate() {\n this.price = await this.getPrice();\n }\n\n async hydrate({self}) {\n self.element.querySelector('input').focus();\n }\n \n render({self}) {\n if(!self.prerendered && !self.initiated) return false;\n return (\n <form> \n <input type=\"number\" bind={this.price} />\n <button disabled={!self.hydrated}> \n Save\n </button>\n </form>\n )\n }\n\n}\n\nexport default Page;\n\n\n\n💡 Componentes que estão otimizados em functional components não tem acesso ao
\nself.
stringEle permite que você persista a instância quando é movida no DOM.
\nVocê pode declarar uma key por instância.
\n\n💡 Se você não declarar a
\nkeyo nullstack irá gerar uma baseada na profundidade da dom.
\n\n🔥 As keys não podem começar com "_." para evitar conflito com as keys geradas pelo Nullstack
\n
As keys devem ser globalmente únicas já que o componente poderá ser movido para qualquer lugar da DOM e não apenas entre os componentes irmãos.
\nAs keys são úteis para preservar o estado em componentes com estado quando você os move para dentro da DOM.
\nIsto é especialmente útil para listas com tamanho dinâmico que invocam os componentes.
\nimport Nullstack from 'nullstack';\nimport Item from './Item';\n\nclass List extends Nullstack {\n\n // ...\n\n async initiate() {\n this.items = await this.getItems();\n }\n \n render({self}) {\n const componentKey = self.key;\n return (\n <ul> \n {this.items.map((item) => (\n <Item key={`${componentKey}-${item.id}`} {...item} />\n ))}\n </ul>\n )\n }\n\n}\n\nexport default Page;\n\nVocê também pode usar as keys para compartilhar a instância entre dois elementos.
\nApenas o primeiro encontro da key irá executar o lifecycle.
import Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n render({amount}) {\n return (\n <div>\n <button onclick={{count: this.count+1}}>\n {this.count} x {amount} = {this.count * amount}\n </button> \n </div>\n )\n }\n\n}\n\nexport default Counter;\n\nimport Nullstack from 'nullstack';\nimport Counter from './Counter';\n\nclass Application extends Nullstack {\n\n render() {\n return (\n <main>\n <Counter key=\"a\" amount={1} />\n <Counter key=\"b\" amount={2} />\n <Counter key=\"b\" amount={3} />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nstringEle permite que você persista a instância quando é movida no DOM.
\nVocê pode declarar uma key por instância.
\n\n\n💡 Se você não declarar a key o nullstack irá gerar uma baseada na profundidade da dom
\n
\n\n🔥 As keys não podem começar com "_." para evitar conflito com as keys geradas pelo Nullstack
\n
As keys devem ser globalmente únicas já que o componente poderá ser movido para qualquer lugar da DOM e não apenas entre os componentes irmãos.
\nAs keys são úteis para preservar o estado em componentes com estado quando você os move para dentro da DOM.
\nIsto é especialmente útil para listas com tamanho dinâmico que invocam os componentes.
\nimport Nullstack from 'nullstack';\nimport Item from './Item';\n\nclass List extends Nullstack {\n\n // ...\n\n async initiate() {\n this.items = await this.getItems();\n }\n \n render({self}) {\n const componentKey = self.key;\n return (\n <ul> \n {this.items.map((item) => (\n <Item key={`${componentKey}-${item.id}`} {...item} />\n ))}\n </ul>\n )\n }\n\n}\n\nexport default Page;\n\nVocê também pode usar as keys para compartilhar a instância entre dois elementos.
\nApenas o primeiro encontro da key irá executar o lifecycle
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n render({amount}) {\n return (\n <div>\n <button onclick={{count: this.count+1}}>\n {this.count} x {amount} = {this.count * amount}\n </button> \n </div>\n )\n }\n\n}\n\nexport default Counter;\n\nimport Nullstack from 'nullstack';\nimport Counter from './Counter';\n\nclass Application extends Nullstack {\n\n render() {\n return (\n <main>\n <Counter key=\"a\" amount={1} />\n <Counter key=\"b\" amount={2} />\n <Counter key=\"b\" amount={3} />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\n⚔ Aprenda sobre requisicao e resposta do servidor.
\n","description":"O objeto self é um proxy no Contexto Nullstack disponível no client e te dá informações sobre o ciclo de vida da instância"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"self da Instância - Nullstack","description":"O objeto self é um proxy no Contexto Nullstack disponível no client e te dá informações sobre o ciclo de vida da instância"}} \ No newline at end of file diff --git a/docs/pt-br/renderizacao-no-servidor.html b/docs/pt-br/renderizacao-no-servidor.html deleted file mode 100644 index c1ec51aa..00000000 --- a/docs/pt-br/renderizacao-no-servidor.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Talvez você queira aprender como criar uma pagina 404 com Nullstack?
-Se você está procurando por outra coisa, você deveria ler a documentação.
-Talvez você queira aprender como criar uma pagina 404 com Nullstack?
-Se você está procurando por outra coisa, você deveria ler a documentação.
-Talvez você queira aprender como criar uma pagina 404 com Nullstack?
\nSe você está procurando por outra coisa, você deveria ler a documentação.
\n","description":"Desculpe, essa não é a página que você está procurando","status":404},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":404,"title":"Página Não Encontrada - Nullstack","description":"Desculpe, essa não é a página que você está procurando"}} \ No newline at end of file diff --git a/docs/pt-br/renderizando-no-servidor.html b/docs/pt-br/renderizando-no-servidor.html deleted file mode 100644 index 25eb6cc1..00000000 --- a/docs/pt-br/renderizando-no-servidor.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from.
-Server-side rendering is good for SEO since it gives as fast as possible crawlable markup for search engines.
-Nullstack starts the application for the user by first serving HTML of only the requested page with no overhead.
-Before serving the HTML, Nullstack will wait for prepare and initiate of all components of that route to be resolved.
-While server-side rendering all server functions run locally without the need to fetch an API, making the process even faster.
-After the document is already painted in the browser, Nullstack loads the javascript client bundle and starts the hydration process.
-No further requests to the server are made to recover the application state during hydration.
-The page head will generate the necessary meta tags for SEO based on the contents of the project and page context keys.
-⚔ Learn about static site generation.
-Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from.
-Server-side rendering is good for SEO since it gives as fast as possible crawlable markup for search engines.
-Nullstack starts the application for the user by first serving HTML of only the requested page with no overhead.
-Before serving the HTML, Nullstack will wait for prepare and initiate of all components of that route to be resolved.
-While server-side rendering all server functions run locally without the need to fetch an API, making the process even faster.
-After the document is already painted in the browser, Nullstack loads the javascript client bundle and starts the hydration process.
-No further requests to the server are made to recover the application state during hydration.
-The page head will generate the necessary meta tags for SEO based on the contents of the project and page context keys.
-⚔ Learn about static site generation.
-Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from.
\nServer-side rendering is good for SEO since it gives as fast as possible crawlable markup for search engines.
\nNullstack starts the application for the user by first serving HTML of only the requested page with no overhead.
\nBefore serving the HTML, Nullstack will wait for prepare and initiate of all components of that route to be resolved.
\nWhile server-side rendering all server functions run locally without the need to fetch an API, making the process even faster.
\nAfter the document is already painted in the browser, Nullstack loads the javascript client bundle and starts the hydration process.
\nNo further requests to the server are made to recover the application state during hydration.
\nThe page head will generate the necessary meta tags for SEO based on the contents of the project and page context keys.
\n⚔ Learn about static site generation.
\n","description":"Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Server-Side Rendering - Nullstack","description":"Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from"}} \ No newline at end of file diff --git a/docs/pt-br/requisicao-e-resposta-do-servidor.html b/docs/pt-br/requisicao-e-resposta-do-servidor.html deleted file mode 100644 index 34a63393..00000000 --- a/docs/pt-br/requisicao-e-resposta-do-servidor.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - -A key do servidor é um proxy em volta de uma instância do Express que roda por baixo dos panos.
-O objeto do servidor está presenta apenas no contexto do servidor.
-As seguintes funções são redirecionadas para o servidor Express:
-getpostputpatchdeleteoptionsheaduse--✨ Se você quer aprender como fazer uma API com Nullstack, este é o caminho.
-
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({server}) {
- server.get('/api/books', (request, response) => {
- response.json({books: []});
- });
- }
-
- // ...
-
-}
-
-export default Application;
-
-Outras keys disponíveis são:
-integerstringobjectimport Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({server}) {
- server.port = 3000;
- server.maximumPayloadSize = '5mb';
- server.cors = {
- origin: 'http://localhost:6969',
- optionsSuccessStatus: 200
- }
- }
-
- // ...
-
-}
-
-export default Application;
-
-O objeto cors será passado como argumento para o plugin do cors no express.
Todo contexto de função do servidor é mesclado com os objetos request e response originais do Express.
Se você der uma resposta manualmente ela irá sobrescrever a response server-side rendering do framework.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async getBooks({request, response}) {
- if(!request.session.user) {
- response.status(401).json({unauthorized: true});
- }
- }
-
- // ...
-
-}
-
-export default Application;
-
-⚔ Aprenda sobre estilos.
-A key do servidor é um proxy em volta de uma instância do Express que roda por baixo dos panos.
-O objeto do servidor está presenta apenas no contexto do servidor.
-As seguintes funções são redirecionadas para o servidor Express:
-getpostputpatchdeleteoptionsheaduse--✨ Se você quer aprender como fazer uma API com Nullstack, este é o caminho.
-
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({server}) {
- server.get('/api/books', (request, response) => {
- response.json({books: []});
- });
- }
-
- // ...
-
-}
-
-export default Application;
-
-Outras keys disponíveis são:
-integerstringobjectimport Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({server}) {
- server.port = 3000;
- server.maximumPayloadSize = '5mb';
- server.cors = {
- origin: 'http://localhost:6969',
- optionsSuccessStatus: 200
- }
- }
-
- // ...
-
-}
-
-export default Application;
-
-O objeto cors será passado como argumento para o plugin do cors no express.
Todo contexto de função do servidor é mesclado com os objetos request e response originais do Express.
Se você der uma resposta manualmente ela irá sobrescrever a response server-side rendering do framework.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async getBooks({request, response}) {
- if(!request.session.user) {
- response.status(401).json({unauthorized: true});
- }
- }
-
- // ...
-
-}
-
-export default Application;
-
-⚔ Aprenda sobre estilos.
-A key do servidor é um proxy em volta de uma instância do Express que roda por baixo dos panos.
\nO objeto do servidor está presenta apenas no contexto do servidor.
\nAs seguintes funções são redirecionadas para o servidor Express:
\ngetpostputpatchdeleteoptionsheaduse\n\n✨ Se você quer aprender como fazer uma API com Nullstack, este é o caminho.
\n
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({server}) {\n server.get('/api/books', (request, response) => {\n response.json({books: []});\n });\n }\n\n // ...\n\n}\n\nexport default Application;\n\nOutras keys disponíveis são:
\nintegerstringobjectimport Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({server}) {\n server.port = 3000;\n server.maximumPayloadSize = '5mb';\n server.cors = {\n origin: 'http://localhost:6969',\n optionsSuccessStatus: 200\n }\n }\n\n // ...\n\n}\n\nexport default Application;\n\nO objeto cors será passado como argumento para o plugin do cors no express.
Todo contexto de função do servidor é mesclado com os objetos request e response originais do Express.
Se você der uma resposta manualmente ela irá sobrescrever a response server-side rendering do framework.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async getBooks({request, response}) {\n if(!request.session.user) {\n response.status(401).json({unauthorized: true});\n }\n }\n\n // ...\n\n}\n\nexport default Application;\n\n⚔ Aprenda sobre estilos.
\n","description":"A key do servidor é um proxy em volta da instância do express, que roda o Nullstack por baixo dos panos"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Requisição e resposta do servidor - Nullstack","description":"A key do servidor é um proxy em volta da instância do express, que roda o Nullstack por baixo dos panos"}} \ No newline at end of file diff --git a/docs/pt-br/rotas-e-parametros.html b/docs/pt-br/rotas-e-parametros.html deleted file mode 100644 index f01f97bb..00000000 --- a/docs/pt-br/rotas-e-parametros.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - -Nullstack tem rotas embutidas, não faria sentido não ser assim já que se espera que aplicações web tenham hyperlinks.
-Qualquer tag pode receber um atributo route, seja um componente, componente interno ou uma tag HTML simples.
import Nullstack from 'nullstack';
-import Page from './Page';
-
-class Application extends Nullstack {
-
- renderHome() {
- return (
- <section> Home </section>
- )
- }
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <Page route="/page" />
- <abbr route="/abbreviations"> Abreviações </abbr>
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Links no Nullstack são tags a simples com o valor de href começando com "/".
<a href="/page/about"> Página About </a>
-
---💡 No lado do cliente o evento de clique modificará o histórico sem recarregar a página.
-
--✨ Você ainda pode atribuir seu próprio evento de clique para a tag sem perder o comportamento do framework.
-
A chave params é um proxy de objeto injetado em cada instância de cliente.
Cada parâmetro da string de query é mapeado para esse objeto.
-Por padrão qualquer chave requisitada deste objeto retornará uma string.
-Se o valor for undefined retornará uma string vazia.
Se o valor for true ou false retornará um boleano, ao invés de uma string.
--🐱💻 Abaixo um exemplo que visita "/books?expanded=true&page=2":
-
import Nullstack from 'nullstack';
-
-class Books extends Nullstack {
-
- async initiate({params}) {
- if(params.expanded) {
- const page = parseInt(params.page) || 1;
- this.books = await this.getBooks({page});
- }
- }
-
-}
-
-export default Books;
-
-Realizar atribuição para uma chave de params causará um redirecionamento para a rota com os parâmetros atualizados.
Quando realizar atribuição para um parâmetro, o valor será convertido para JSON antes de ser definido.
---💡 Redirecionamentos funcionam em lotes, então não há perca de performance em multiplas atribuições.
-
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- handleClick({params}) {
- params.filter = '';
- params.page = 1;
- }
-
-}
-
-export default Paginator;
-
-Atribuir uma string vazia a um parâmetro irá removê-lo da url.
-Parte da rota pode ser uma expressão começada com ":" segida por um nome de parâmetro.
-Esse valor será comparado com qualquer string na mesma posição de diretório.
-O valor da string na URL será atribuído para o contexto, parâmetros e funções abaixo desse ponto na hierarquia terão acesso a nova chave.
---🐱💻 Abaixo um exemplo que visita "/category/suspense?page=2":
-
import Nullstack from 'nullstack';
-
-class Books extends Nullstack {
-
- async initiate({params}) {
- const page = parseInt(params.page) || 1;
- const category = params.slug;
- this.books = await this.getBooks({category, page});
- }
-
-}
-
-export default Books;
-
-import Nullstack from 'nullstack';
-import Books from './Books';
-
-class Application extends Nullstack {
-
- render() {
- <main>
- <Books route="/category/:slug">
- </main>
- }
-
-}
-
-export default Application;
-
-Quando um segmento dinâmico é alterado, como por exemplo mover de "/category/suspense" para "/category/comedy", o componente será desfeito e uma nova instância será criada.
-Mudar um parâmetro de consulta não re-instnaciará o componente.
-Os filhos do componente não serão re-instanciados automaticamente, você pode definir a mesma rota para os filhos ou fazer isso manualmente se desejar esse comportamento.
---💡 O comportamento mencionado acima resolve muitos dos problemas que você teria normalmente que lidar manualmente.
-
Curingas são rotas declaradas com "*" como valor do atributo
-Essas rotas corresponderão a qualquer coisa se nada acima delas corresponder a URL requisitada.
-import Nullstack from 'nullstack';
-import Home from './Home';
-
-class Application extends Nullstack {
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <div route="*"> Curinga </div>
- </main>
- )
- }
-
-}
-
-Curingas podem ser prefixados com um segmento.
---✨ Isso é especialmente útil para engines que podem ser montadas em suas aplicações.
-
import Nullstack from 'nullstack';
-import Home from './Home';
-import BlogEngine from './BlogEngine';
-
-class Application extends Nullstack {
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <BlogEngine route="/blog/*" />
- </main>
- )
- }
-
-}
-
-A chave router é um proxy de objeto injetado em cada instância de cliente.
O router tem duas chaves:
urlpathA chave url retorna tudo depois do domínio, incluindo o caminho e os parâmetros de query como uma string.
A chave path retorna apenas o caminho sem os parâmetros de consulta.
--💡 Ambas as chaves acima automaticamente removem a barra final por conveniência.
-
Atribuir a url ou path causará redirecionamento.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- prepare({router}) {
- if(router.path == '/') {
- router.path = '/dashboard';
- }
- }
-
-}
-
---💡 Por baixo dos panos tags
-aeparamsusam orouter.
Atualizar router.url ou router.path irá gerar um evento personalizado.
import Nullstack from 'nullstack';
-
-class Analytics extends Nullstack {
-
- hydrate({router}) {
- window.addEventListener(router.event, () => {
- console.log(router.url);
- });
- }
-
-}
-
-export default Analytics;
-
-Tags de âncora aceitam somente alguns atributos especiais convenientes além do href comum.
Você pode atribuir o atributo params com um objeto como valor.
O caminho permanecerá o mesmo do caminho atual do roteador, mas os params serão substituídos pelos novos parâmetros que você especificar.
<a params={{page: 1}}> Primeira Página </a>
-
-E você deseja apenas atualizar alguns parâmetros e manter outros, você pode usar o operador javascript spread para isso.
-<a params={{...params, page: 1}}> Primeira Página </a>
-
-Você pode definir o atributo path com uma string começando com "/" e sem parâmetros de query.
Os parâmetros permanecerão os mesmos, mas, o path será atualizado.
<a path="/category/suspense"> Livros de Suspense </a>
-
-Ambos os atributos acima podem ser utilizados ao mesmo tempo.
-<a path="/category/suspense" params={{...params, page: 1}}> Livros de Suspense </a>
-
-A primeira rota a ser correspondida será renderizada.
-Os outros elementos com uma rota não serão renderizados, no entanto, os elementos no mesmo nível sem um atributo route serão renderizados normalmente.
O roteador irá procurar uma rota por nível de profundidade DOM, isso permite que você tenha um comportamento de roteamento aninhado.
-import Nullstack from 'nullstack';
-import Home from './Home';
-
-class Application extends Nullstack {
-
- renderPage() {
- return (
- <section>
- <div route="/page/about"> About Page </div>
- <div route="/page/contact"> Contact Page </div>
- </section>
- )
- }
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <Page route="/page/:slug" />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-⚔ Aprenda sobre vínculos bidirecionais.
-Nullstack tem rotas embutidas, não faria sentido não ser assim já que se espera que aplicações web tenham hyperlinks.
-Qualquer tag pode receber um atributo route, seja um componente, componente interno ou uma tag HTML simples.
import Nullstack from 'nullstack';
-import Page from './Page';
-
-class Application extends Nullstack {
-
- renderHome() {
- return (
- <section> Home </section>
- )
- }
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <Page route="/page" />
- <abbr route="/abbreviations"> Abreviações </abbr>
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Links no Nullstack são tags a simples com o valor de href começando com "/".
<a href="/page/about"> Página About </a>
-
---💡 No lado do cliente o evento de clique modificará o histórico sem recarregar a página.
-
--✨ Você ainda pode atribuir seu próprio evento de clique para a tag sem perder o comportamento do framework.
-
A chave params é um proxy de objeto injetado em cada instância de cliente.
Cada parâmetro da string de query é mapeado para esse objeto.
-Por padrão qualquer chave requisitada deste objeto retornará uma string.
-Se o valor for undefined retornará uma string vazia.
Se o valor for true ou false retornará um boleano, ao invés de uma string.
--🐱💻 Abaixo um exemplo que visita "/books?expanded=true&page=2":
-
import Nullstack from 'nullstack';
-
-class Books extends Nullstack {
-
- async initiate({params}) {
- if(params.expanded) {
- const page = parseInt(params.page) || 1;
- this.books = await this.getBooks({page});
- }
- }
-
-}
-
-export default Books;
-
-Realizar atribuição para uma chave de params causará um redirecionamento para a rota com os parâmetros atualizados.
Quando realizar atribuição para um parâmetro, o valor será convertido para JSON antes de ser definido.
---💡 Redirecionamentos funcionam em lotes, então não há perca de performance em multiplas atribuições.
-
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- handleClick({params}) {
- params.filter = '';
- params.page = 1;
- }
-
-}
-
-export default Paginator;
-
-Atribuir uma string vazia a um parâmetro irá removê-lo da url.
-Parte da rota pode ser uma expressão começada com ":" segida por um nome de parâmetro.
-Esse valor será comparado com qualquer string na mesma posição de diretório.
-O valor da string na URL será atribuído para o contexto, parâmetros e funções abaixo desse ponto na hierarquia terão acesso a nova chave.
---🐱💻 Abaixo um exemplo que visita "/category/suspense?page=2":
-
import Nullstack from 'nullstack';
-
-class Books extends Nullstack {
-
- async initiate({params}) {
- const page = parseInt(params.page) || 1;
- const category = params.slug;
- this.books = await this.getBooks({category, page});
- }
-
-}
-
-export default Books;
-
-import Nullstack from 'nullstack';
-import Books from './Books';
-
-class Application extends Nullstack {
-
- render() {
- <main>
- <Books route="/category/:slug">
- </main>
- }
-
-}
-
-export default Application;
-
-Quando um segmento dinâmico é alterado, como por exemplo mover de "/category/suspense" para "/category/comedy", o componente será desfeito e uma nova instância será criada.
-Mudar um parâmetro de consulta não re-instnaciará o componente.
-Os filhos do componente não serão re-instanciados automaticamente, você pode definir a mesma rota para os filhos ou fazer isso manualmente se desejar esse comportamento.
---💡 O comportamento mencionado acima resolve muitos dos problemas que você teria normalmente que lidar manualmente.
-
Curingas são rotas declaradas com "*" como valor do atributo
-Essas rotas corresponderão a qualquer coisa se nada acima delas corresponder a URL requisitada.
-import Nullstack from 'nullstack';
-import Home from './Home';
-
-class Application extends Nullstack {
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <div route="*"> Curinga </div>
- </main>
- )
- }
-
-}
-
-Curingas podem ser prefixados com um segmento.
---✨ Isso é especialmente útil para engines que podem ser montadas em suas aplicações.
-
import Nullstack from 'nullstack';
-import Home from './Home';
-import BlogEngine from './BlogEngine';
-
-class Application extends Nullstack {
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <BlogEngine route="/blog/*" />
- </main>
- )
- }
-
-}
-
-A chave router é um proxy de objeto injetado em cada instância de cliente.
O router tem duas chaves:
urlpathA chave url retorna tudo depois do domínio, incluindo o caminho e os parâmetros de query como uma string.
A chave path retorna apenas o caminho sem os parâmetros de consulta.
--💡 Ambas as chaves acima automaticamente removem a barra final por conveniência.
-
Atribuir a url ou path causará redirecionamento.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- prepare({router}) {
- if(router.path == '/') {
- router.path = '/dashboard';
- }
- }
-
-}
-
---💡 Por baixo dos panos tags
-aeparamsusam orouter.
Atualizar router.url ou router.path irá gerar um evento personalizado.
import Nullstack from 'nullstack';
-
-class Analytics extends Nullstack {
-
- hydrate({router}) {
- window.addEventListener(router.event, () => {
- console.log(router.url);
- });
- }
-
-}
-
-export default Analytics;
-
-Tags de âncora aceitam somente alguns atributos especiais convenientes além do href comum.
Você pode atribuir o atributo params com um objeto como valor.
O caminho permanecerá o mesmo do caminho atual do roteador, mas os params serão substituídos pelos novos parâmetros que você especificar.
<a params={{page: 1}}> Primeira Página </a>
-
-E você deseja apenas atualizar alguns parâmetros e manter outros, você pode usar o operador javascript spread para isso.
-<a params={{...params, page: 1}}> Primeira Página </a>
-
-Você pode definir o atributo path com uma string começando com "/" e sem parâmetros de query.
Os parâmetros permanecerão os mesmos, mas, o path será atualizado.
<a path="/category/suspense"> Livros de Suspense </a>
-
-Ambos os atributos acima podem ser utilizados ao mesmo tempo.
-<a path="/category/suspense" params={{...params, page: 1}}> Livros de Suspense </a>
-
-A primeira rota a ser correspondida será renderizada.
-Os outros elementos com uma rota não serão renderizados, no entanto, os elementos no mesmo nível sem um atributo route serão renderizados normalmente.
O roteador irá procurar uma rota por nível de profundidade DOM, isso permite que você tenha um comportamento de roteamento aninhado.
-import Nullstack from 'nullstack';
-import Home from './Home';
-
-class Application extends Nullstack {
-
- renderPage() {
- return (
- <section>
- <div route="/page/about"> About Page </div>
- <div route="/page/contact"> Contact Page </div>
- </section>
- )
- }
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <Page route="/page/:slug" />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-⚔ Aprenda sobre vínculos bidirecionais.
-Nullstack tem rotas embutidas, não faria sentido não ser assim já que se espera que aplicações web tenham hyperlinks.
\nQualquer tag pode receber um atributo route, seja um componente, componente interno ou uma tag HTML simples.
import Nullstack from 'nullstack';\nimport Page from './Page';\n\nclass Application extends Nullstack {\n\n renderHome() {\n return (\n <section> Home </section>\n )\n }\n \n render({count}) {\n return (\n <main>\n <Home route=\"/\" />\n <Page route=\"/page\" />\n <abbr route=\"/abbreviations\"> Abreviações </abbr>\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nLinks no Nullstack são tags a simples com o valor de href começando com "/".
<a href=\"/page/about\"> Página About </a>\n\n\n\n💡 No lado do cliente o evento de clique modificará o histórico sem recarregar a página.
\n
\n\n✨ Você ainda pode atribuir seu próprio evento de clique para a tag sem perder o comportamento do framework.
\n
A chave params é um proxy de objeto injetado em cada instância de cliente.
Cada parâmetro da string de query é mapeado para esse objeto.
\nPor padrão qualquer chave requisitada deste objeto retornará uma string.
\nSe o valor for undefined retornará uma string vazia.
Se o valor for true ou false retornará um boleano, ao invés de uma string.
\n\n🐱💻 Abaixo um exemplo que visita "/books?expanded=true&page=2":
\n
import Nullstack from 'nullstack';\n\nclass Books extends Nullstack {\n\n async initiate({params}) {\n if(params.expanded) {\n const page = parseInt(params.page) || 1;\n this.books = await this.getBooks({page});\n }\n }\n\n}\n\nexport default Books;\n\nRealizar atribuição para uma chave de params causará um redirecionamento para a rota com os parâmetros atualizados.
Quando realizar atribuição para um parâmetro, o valor será convertido para JSON antes de ser definido.
\n\n\n💡 Redirecionamentos funcionam em lotes, então não há perca de performance em multiplas atribuições.
\n
import Nullstack from 'nullstack';\n\nclass Paginator extends Nullstack {\n\n handleClick({params}) {\n params.filter = '';\n params.page = 1;\n }\n\n}\n\nexport default Paginator;\n\nAtribuir uma string vazia a um parâmetro irá removê-lo da url.
\nParte da rota pode ser uma expressão começada com ":" segida por um nome de parâmetro.
\nEsse valor será comparado com qualquer string na mesma posição de diretório.
\nO valor da string na URL será atribuído para o contexto, parâmetros e funções abaixo desse ponto na hierarquia terão acesso a nova chave.
\n\n\n🐱💻 Abaixo um exemplo que visita "/category/suspense?page=2":
\n
import Nullstack from 'nullstack';\n\nclass Books extends Nullstack {\n\n async initiate({params}) {\n const page = parseInt(params.page) || 1;\n const category = params.slug;\n this.books = await this.getBooks({category, page});\n }\n\n}\n\nexport default Books;\n\nimport Nullstack from 'nullstack';\nimport Books from './Books';\n\nclass Application extends Nullstack {\n\n render() {\n <main>\n <Books route=\"/category/:slug\">\n </main>\n }\n\n}\n\nexport default Application;\n\nQuando um segmento dinâmico é alterado, como por exemplo mover de "/category/suspense" para "/category/comedy", o componente será desfeito e uma nova instância será criada.
\nMudar um parâmetro de consulta não re-instnaciará o componente.
\nOs filhos do componente não serão re-instanciados automaticamente, você pode definir a mesma rota para os filhos ou fazer isso manualmente se desejar esse comportamento.
\n\n\n💡 O comportamento mencionado acima resolve muitos dos problemas que você teria normalmente que lidar manualmente.
\n
Curingas são rotas declaradas com "*" como valor do atributo
\nEssas rotas corresponderão a qualquer coisa se nada acima delas corresponder a URL requisitada.
\nimport Nullstack from 'nullstack';\nimport Home from './Home';\n\nclass Application extends Nullstack {\n\n render({count}) {\n return (\n <main>\n <Home route=\"/\" />\n <div route=\"*\"> Curinga </div>\n </main>\n )\n }\n\n}\n\nCuringas podem ser prefixados com um segmento.
\n\n\n✨ Isso é especialmente útil para engines que podem ser montadas em suas aplicações.
\n
import Nullstack from 'nullstack';\nimport Home from './Home';\nimport BlogEngine from './BlogEngine';\n\nclass Application extends Nullstack {\n\n render({count}) {\n return (\n <main>\n <Home route=\"/\" />\n <BlogEngine route=\"/blog/*\" />\n </main>\n )\n }\n\n}\n\nA chave router é um proxy de objeto injetado em cada instância de cliente.
O router tem duas chaves:
urlpathA chave url retorna tudo depois do domínio, incluindo o caminho e os parâmetros de query como uma string.
A chave path retorna apenas o caminho sem os parâmetros de consulta.
\n\n💡 Ambas as chaves acima automaticamente removem a barra final por conveniência.
\n
Atribuir a url ou path causará redirecionamento.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n prepare({router}) {\n if(router.path == '/') {\n router.path = '/dashboard';\n }\n }\n\n}\n\n\n\n💡 Por baixo dos panos tags
\naeparamsusam orouter.
Atualizar router.url ou router.path irá gerar um evento personalizado.
import Nullstack from 'nullstack';\n\nclass Analytics extends Nullstack {\n\n hydrate({router}) {\n window.addEventListener(router.event, () => {\n console.log(router.url);\n });\n }\n\n}\n\nexport default Analytics;\n\nTags de âncora aceitam somente alguns atributos especiais convenientes além do href comum.
Você pode atribuir o atributo params com um objeto como valor.
O caminho permanecerá o mesmo do caminho atual do roteador, mas os params serão substituídos pelos novos parâmetros que você especificar.
<a params={{page: 1}}> Primeira Página </a>\n\nE você deseja apenas atualizar alguns parâmetros e manter outros, você pode usar o operador javascript spread para isso.
\n<a params={{...params, page: 1}}> Primeira Página </a>\n\nVocê pode definir o atributo path com uma string começando com "/" e sem parâmetros de query.
Os parâmetros permanecerão os mesmos, mas, o path será atualizado.
<a path=\"/category/suspense\"> Livros de Suspense </a>\n\nAmbos os atributos acima podem ser utilizados ao mesmo tempo.
\n<a path=\"/category/suspense\" params={{...params, page: 1}}> Livros de Suspense </a>\n\nA primeira rota a ser correspondida será renderizada.
\nOs outros elementos com uma rota não serão renderizados, no entanto, os elementos no mesmo nível sem um atributo route serão renderizados normalmente.
O roteador irá procurar uma rota por nível de profundidade DOM, isso permite que você tenha um comportamento de roteamento aninhado.
\nimport Nullstack from 'nullstack';\nimport Home from './Home';\n\nclass Application extends Nullstack {\n\n renderPage() {\n return (\n <section>\n <div route=\"/page/about\"> About Page </div>\n <div route=\"/page/contact\"> Contact Page </div>\n </section>\n )\n }\n \n render({count}) {\n return (\n <main>\n <Home route=\"/\" />\n <Page route=\"/page/:slug\" />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\n⚔ Aprenda sobre vínculos bidirecionais.
\n","description":"Nullstack tem rotas embutidas, não faria sentido não ser assim já que se espera que aplicações web tenham hyperlinks."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Rotas e Parâmetros - Nullstack","description":"Nullstack tem rotas embutidas, não faria sentido não ser assim já que se espera que aplicações web tenham hyperlinks."}} \ No newline at end of file diff --git a/docs/pt-br/service-worker.html b/docs/pt-br/service-worker.html deleted file mode 100644 index bb009504..00000000 --- a/docs/pt-br/service-worker.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - -objectEle te dá controle granular do comportamento do seu PWA.
-Chaves do worker serão usadas para gerar o arquivo do service worker e devem ser setadas durante o processo de inicialização.
Chaves do worker são congeladas após o processo de inicialização.
As seguintes keys estão disponíveis no objeto durante a inicialização:
-booleanstring array (relative paths)objectA chave enabled define se o service worker será registrado automaticamente pelo Nullstack.
Por padrão a chave enabled é setada como true no modo de produção e false no modo de desenvolvimento.
O array preload é composto por caminhos que serão cacheados quando o service worker for instalado.
Os assets requeridos para inicializar a aplicação serão pré-carregados automaticamente, e você deverá apenas as páginas extras que você quer que estejam disponíveis em modo offline.
-import Nullstack from 'nullstack';
-import path from 'path';
-import {readdirSync} from 'fs';
-
-class Application extends Nullstack {
-
- static async start({worker}) {
- const articles = readdirSync(path.join(__dirname, '..', 'articles'));
- worker.preload = [
- ...articles.map((article) => '/' + article.replace('.md', '')),
- '/nullstack.svg',
- '/documentation',
- '/components'
- ]
- }
-
- // ...
-
-}
-
-export default Application;
-
---💡 O exemplo acima foi extraido deste repositório e permite que a documentação esteja totalmente acessível em modo offline.
-
As seguintes chaves estão disponíveis como readonly no contexto do cliente:
-booleanstring array (relative paths)booleanbooleanbooleanBeforeInstallPromptEventServiceWorkerRegistrationobjectAs seguintes chaves estão disponíveis como readwrite no contexto do cliente:
-objectA chave responsive determina se a aplicação tem todas as respostas necessárias para renderizar a página atual.
O Nullstack irá tentar manter sua aplicação respondendo o maior tempo possível e setará a chave para false somente quando não houver mais alternativas de recuperar qualquer resposta da rede ou offline usando a estratégia de busca para o ambiente.
A chave online irá monitorar os eventos da rede e re-renderizar a aplicação quando o valor de navigator.onLine mudar.
Quando a aplicação voltar a ficar online o Nullstack irá tentar fazer a aplicação responder novamente e re-renderizar se necessário.
-import Nullstack from 'nullstack';
-// ...
-
-class Application extends Nullstack {
-
- // ...
-
- render({worker}) {
- if(!worker.responsive) {
- return <OfflineWarning />
- }
- return (
- <main>
- <Home route="/" />
- </main>
- )
- }
-
-}
-
-Você pode acessar a registration e installation do service worker atual pela chave worker para controlar o fluxo do seu PWA.
A chave registration se refere ao registro do service worker e só estará disponível uma vez que o processo de registro esteja completo.
A chave installation se refere a instalação delegada no evento do prompt e apenas estará disponível se o evento beforeinstallprompt ocorrer.
import Nullstack from 'nullstack';
-
-class PWAInstaller extends Nullstack {
-
- installed = false;
- hidden = false;
-
- async prompt({worker}) {
- try {
- worker.installation.prompt();
- const {outcome} = await worker.installation.userChoice;
- if (outcome === 'accepted') {
- console.log('User accepted the A2HS prompt');
- } else {
- console.log('User dismissed the A2HS prompt');
- }
- } finally {
- this.hidden = true;
- }
- }
-
- render({worker, project}) {
- if(this.hidden) return false;
- if(!worker.installation) return false;
- return (
- <div>
- <img src={project.favicon} />
- <p> Do you want to add {project.name} to your home screen?</p>
- <button onclick={this.prompt}> Install </button>
- <button onclick={{hidden: true}}> Not Now </button>
- </div>
- )
- }
-
-}
-
-export default PWAInstaller;
-
-Quando uma função do servidor é chamada o fetching será setado como true até a requisição ser resolvida.
Quando uma função do servidor é chamada a chave com o nome da função do servidor invocada será setada como true na chave loading até a requisição ser resolvida.
Qualquer chave que for chamada no objeto loading sempre irá retornar um valor booleano ao invés de undefined por consistência.
Quando o servidor estiver emulando o contexto do cliente para renderização no lado do servidor, todas as chaves de loading vão sempre retornar false, pulando multiplos ciclos de render por performance.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- static async save() {
- // ...
- }
-
- async submit() {
- await this.save();
- }
-
- render({worker}) {
- return (
- <form onsubmit={this.save}>
- {worker.fetching &&
- <span> loading... </span>
- }
- <button disabled={worker.loading.save}>
- Save
- </button>
- </form>
- )
- }
-
-}
-
-export default Page;
-
-Você pode usar a chave headers para configurar as headers que o worker usará na requisição para uma função do servidor
--🔥 headers serão ignorados quando uma função do servidor for chamada durante o processo de renderização do lado do servidor
-
import Nullstack from 'nullstack';
-
-class LoginPage extends Nullstack {
-
- // ...
-
- async submit({worker}) {
- // ...
- this.headers['Authorization'] = `Bearer ${token}`;
- // ...
- }
-
- static async authorize({request}) {
- const authorization = request.headers['Authorization'];
- // ...
- }
-
- // ...
-
-}
-
-
-export default LoginPage;
-
---✨ Aprenda mais sobre o requisições e respostas do servidor
-
worker.responsive e o worker.online estiverem setados como false;worker.responsive e worker.online estiverem setados como false;O Nullstack irá instalar automaticamente seu service worker se enabled estiver setado como true com os seguintes eventos:
installactivatefetchVocê pode sobreescrever qualquer um desses eventos criando um service-worker.js na pasta public;
-Se qualquer uma das palavras chaves acima for encontrada o Nullstack injetará sua função no código do service worker ao invés do padrão.
-Por conveniência uma chave chamada context é injetada no self do service worker com as seguintes chaves:
workerprojectenvironmentfunction activate(event) {
- event.waitUntil(async function() {
- const cacheNames = await caches.keys();
- const cachesToDelete = cacheNames.filter(cacheName => cacheName !== self.context.environment.key);
- await Promise.all(cachesToDelete.map((cacheName) => caches.delete(cacheName)));
- if (self.registration.navigationPreload) {
- await self.registration.navigationPreload.enable();
- }
- self.clients.claim();
- }());
-}
-
-self.addEventListener('activate', activate);
-
---💡 O exemplo acima foi extraido do service worker gerado e usa
-self.context.enviroment.key
objectEle te dá controle granular do comportamento do seu PWA.
-Chaves do worker serão usadas para gerar o arquivo do service worker e devem ser setadas durante o processo de inicialização.
Chaves do worker são congeladas após o processo de inicialização.
As seguintes keys estão disponíveis no objeto durante a inicialização:
-booleanstring array (relative paths)objectA chave enabled define se o service worker será registrado automaticamente pelo Nullstack.
Por padrão a chave enabled é setada como true no modo de produção e false no modo de desenvolvimento.
O array preload é composto por caminhos que serão cacheados quando o service worker for instalado.
Os assets requeridos para inicializar a aplicação serão pré-carregados automaticamente, e você deverá apenas as páginas extras que você quer que estejam disponíveis em modo offline.
-import Nullstack from 'nullstack';
-import path from 'path';
-import {readdirSync} from 'fs';
-
-class Application extends Nullstack {
-
- static async start({worker}) {
- const articles = readdirSync(path.join(__dirname, '..', 'articles'));
- worker.preload = [
- ...articles.map((article) => '/' + article.replace('.md', '')),
- '/nullstack.svg',
- '/documentation',
- '/components'
- ]
- }
-
- // ...
-
-}
-
-export default Application;
-
---💡 O exemplo acima foi extraido deste repositório e permite que a documentação esteja totalmente acessível em modo offline.
-
As seguintes chaves estão disponíveis como readonly no contexto do cliente:
-booleanstring array (relative paths)booleanbooleanbooleanBeforeInstallPromptEventServiceWorkerRegistrationobjectAs seguintes chaves estão disponíveis como readwrite no contexto do cliente:
-objectA chave responsive determina se a aplicação tem todas as respostas necessárias para renderizar a página atual.
O Nullstack irá tentar manter sua aplicação respondendo o maior tempo possível e setará a chave para false somente quando não houver mais alternativas de recuperar qualquer resposta da rede ou offline usando a estratégia de busca para o ambiente.
A chave online irá monitorar os eventos da rede e re-renderizar a aplicação quando o valor de navigator.onLine mudar.
Quando a aplicação voltar a ficar online o Nullstack irá tentar fazer a aplicação responder novamente e re-renderizar se necessário.
-import Nullstack from 'nullstack';
-// ...
-
-class Application extends Nullstack {
-
- // ...
-
- render({worker}) {
- if(!worker.responsive) {
- return <OfflineWarning />
- }
- return (
- <main>
- <Home route="/" />
- </main>
- )
- }
-
-}
-
-Você pode acessar a registration e installation do service worker atual pela chave worker para controlar o fluxo do seu PWA.
A chave registration se refere ao registro do service worker e só estará disponível uma vez que o processo de registro esteja completo.
A chave installation se refere a instalação delegada no evento do prompt e apenas estará disponível se o evento beforeinstallprompt ocorrer.
import Nullstack from 'nullstack';
-
-class PWAInstaller extends Nullstack {
-
- installed = false;
- hidden = false;
-
- async prompt({worker}) {
- try {
- worker.installation.prompt();
- const {outcome} = await worker.installation.userChoice;
- if (outcome === 'accepted') {
- console.log('User accepted the A2HS prompt');
- } else {
- console.log('User dismissed the A2HS prompt');
- }
- } finally {
- this.hidden = true;
- }
- }
-
- render({worker, project}) {
- if(this.hidden) return false;
- if(!worker.installation) return false;
- return (
- <div>
- <img src={project.favicon} />
- <p> Do you want to add {project.name} to your home screen?</p>
- <button onclick={this.prompt}> Install </button>
- <button onclick={{hidden: true}}> Not Now </button>
- </div>
- )
- }
-
-}
-
-export default PWAInstaller;
-
-Quando uma função do servidor é chamada o fetching será setado como true até a requisição ser resolvida.
Quando uma função do servidor é chamada a chave com o nome da função do servidor invocada será setada como true na chave loading até a requisição ser resolvida.
Qualquer chave que for chamada no objeto loading sempre irá retornar um valor booleano ao invés de undefined por consistência.
Quando o servidor estiver emulando o contexto do cliente para renderização no lado do servidor, todas as chaves de loading vão sempre retornar false, pulando multiplos ciclos de render por performance.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- static async save() {
- // ...
- }
-
- async submit() {
- await this.save();
- }
-
- render({worker}) {
- return (
- <form onsubmit={this.save}>
- {worker.fetching &&
- <span> loading... </span>
- }
- <button disabled={worker.loading.save}>
- Save
- </button>
- </form>
- )
- }
-
-}
-
-export default Page;
-
-Você pode usar a chave headers para configurar as headers que o worker usará na requisição para uma função do servidor
--🔥 headers serão ignorados quando uma função do servidor for chamada durante o processo de renderização do lado do servidor
-
import Nullstack from 'nullstack';
-
-class LoginPage extends Nullstack {
-
- // ...
-
- async submit({worker}) {
- // ...
- this.headers['Authorization'] = `Bearer ${token}`;
- // ...
- }
-
- static async authorize({request}) {
- const authorization = request.headers['Authorization'];
- // ...
- }
-
- // ...
-
-}
-
-
-export default LoginPage;
-
---✨ Aprenda mais sobre o requisições e respostas do servidor
-
worker.responsive e o worker.online estiverem setados como false;worker.responsive e worker.online estiverem setados como false;O Nullstack irá instalar automaticamente seu service worker se enabled estiver setado como true com os seguintes eventos:
installactivatefetchVocê pode sobreescrever qualquer um desses eventos criando um service-worker.js na pasta public;
-Se qualquer uma das palavras chaves acima for encontrada o Nullstack injetará sua função no código do service worker ao invés do padrão.
-Por conveniência uma chave chamada context é injetada no self do service worker com as seguintes chaves:
workerprojectenvironmentfunction activate(event) {
- event.waitUntil(async function() {
- const cacheNames = await caches.keys();
- const cachesToDelete = cacheNames.filter(cacheName => cacheName !== self.context.environment.key);
- await Promise.all(cachesToDelete.map((cacheName) => caches.delete(cacheName)));
- if (self.registration.navigationPreload) {
- await self.registration.navigationPreload.enable();
- }
- self.clients.claim();
- }());
-}
-
-self.addEventListener('activate', activate);
-
---💡 O exemplo acima foi extraido do service worker gerado e usa
-self.context.enviroment.key
objectEle te dá controle granular do comportamento do seu PWA.
\nChaves do worker serão usadas para gerar o arquivo do service worker e devem ser setadas durante o processo de inicialização.
Chaves do worker são congeladas após o processo de inicialização.
As seguintes keys estão disponíveis no objeto durante a inicialização:
\nbooleanstring array (relative paths)objectA chave enabled define se o service worker será registrado automaticamente pelo Nullstack.
Por padrão a chave enabled é setada como true no modo de produção e false no modo de desenvolvimento.
O array preload é composto por caminhos que serão cacheados quando o service worker for instalado.
Os assets requeridos para inicializar a aplicação serão pré-carregados automaticamente, e você deverá apenas as páginas extras que você quer que estejam disponíveis em modo offline.
\nimport Nullstack from 'nullstack';\nimport path from 'path';\nimport {readdirSync} from 'fs';\n\nclass Application extends Nullstack {\n\n static async start({worker}) {\n const articles = readdirSync(path.join(__dirname, '..', 'articles'));\n worker.preload = [\n ...articles.map((article) => '/' + article.replace('.md', '')),\n '/nullstack.svg',\n '/documentation',\n '/components'\n ]\n }\n \n // ...\n\n}\n\nexport default Application;\n\n\n\n💡 O exemplo acima foi extraido deste repositório e permite que a documentação esteja totalmente acessível em modo offline.
\n
As seguintes chaves estão disponíveis como readonly no contexto do cliente:
\nbooleanstring array (relative paths)booleanbooleanbooleanBeforeInstallPromptEventServiceWorkerRegistrationobjectAs seguintes chaves estão disponíveis como readwrite no contexto do cliente:
\nobjectA chave responsive determina se a aplicação tem todas as respostas necessárias para renderizar a página atual.
O Nullstack irá tentar manter sua aplicação respondendo o maior tempo possível e setará a chave para false somente quando não houver mais alternativas de recuperar qualquer resposta da rede ou offline usando a estratégia de busca para o ambiente.
A chave online irá monitorar os eventos da rede e re-renderizar a aplicação quando o valor de navigator.onLine mudar.
Quando a aplicação voltar a ficar online o Nullstack irá tentar fazer a aplicação responder novamente e re-renderizar se necessário.
\nimport Nullstack from 'nullstack';\n// ...\n\nclass Application extends Nullstack {\n \n // ...\n\n render({worker}) {\n if(!worker.responsive) {\n return <OfflineWarning />\n }\n return (\n <main>\n <Home route=\"/\" />\n </main>\n )\n }\n\n}\n\nVocê pode acessar a registration e installation do service worker atual pela chave worker para controlar o fluxo do seu PWA.
A chave registration se refere ao registro do service worker e só estará disponível uma vez que o processo de registro esteja completo.
A chave installation se refere a instalação delegada no evento do prompt e apenas estará disponível se o evento beforeinstallprompt ocorrer.
import Nullstack from 'nullstack';\n\nclass PWAInstaller extends Nullstack {\n\n installed = false;\n hidden = false;\n\n async prompt({worker}) {\n try {\n worker.installation.prompt();\n const {outcome} = await worker.installation.userChoice;\n if (outcome === 'accepted') {\n console.log('User accepted the A2HS prompt');\n } else {\n console.log('User dismissed the A2HS prompt');\n }\n } finally {\n this.hidden = true;\n }\n }\n \n render({worker, project}) {\n if(this.hidden) return false;\n if(!worker.installation) return false;\n return (\n <div>\n <img src={project.favicon} />\n <p> Do you want to add {project.name} to your home screen?</p>\n <button onclick={this.prompt}> Install </button>\n <button onclick={{hidden: true}}> Not Now </button>\n </div>\n )\n }\n\n}\n\nexport default PWAInstaller;\n\nQuando uma função do servidor é chamada o fetching será setado como true até a requisição ser resolvida.
Quando uma função do servidor é chamada a chave com o nome da função do servidor invocada será setada como true na chave loading até a requisição ser resolvida.
Qualquer chave que for chamada no objeto loading sempre irá retornar um valor booleano ao invés de undefined por consistência.
Quando o servidor estiver emulando o contexto do cliente para renderização no lado do servidor, todas as chaves de loading vão sempre retornar false, pulando multiplos ciclos de render por performance.
import Nullstack from 'nullstack';\n\nclass Page extends Nullstack {\n\n static async save() {\n // ...\n }\n\n async submit() {\n await this.save();\n }\n \n render({worker}) {\n return (\n <form onsubmit={this.save}> \n {worker.fetching && \n <span> loading... </span>\n }\n <button disabled={worker.loading.save}> \n Save\n </button>\n </form>\n )\n }\n\n}\n\nexport default Page;\n\nVocê pode usar a chave headers para configurar as headers que o worker usará na requisição para uma função do servidor
\n\n🔥 headers serão ignorados quando uma função do servidor for chamada durante o processo de renderização do lado do servidor
\n
import Nullstack from 'nullstack';\n\nclass LoginPage extends Nullstack {\n\n // ...\n\n async submit({worker}) {\n // ...\n this.headers['Authorization'] = `Bearer ${token}`;\n // ...\n }\n\n static async authorize({request}) {\n const authorization = request.headers['Authorization'];\n // ...\n }\n \n // ...\n\n}\n\n\nexport default LoginPage;\n\n\n\n✨ Aprenda mais sobre o requisições e respostas do servidor
\n
worker.responsive e o worker.online estiverem setados como false;worker.responsive e worker.online estiverem setados como false;O Nullstack irá instalar automaticamente seu service worker se enabled estiver setado como true com os seguintes eventos:
installactivatefetchVocê pode sobreescrever qualquer um desses eventos criando um service-worker.js na pasta public;
\nSe qualquer uma das palavras chaves acima for encontrada o Nullstack injetará sua função no código do service worker ao invés do padrão.
\nPor conveniência uma chave chamada context é injetada no self do service worker com as seguintes chaves:
workerprojectenvironmentfunction activate(event) {\n event.waitUntil(async function() {\n const cacheNames = await caches.keys();\n const cachesToDelete = cacheNames.filter(cacheName => cacheName !== self.context.environment.key);\n await Promise.all(cachesToDelete.map((cacheName) => caches.delete(cacheName)));\n if (self.registration.navigationPreload) {\n await self.registration.navigationPreload.enable();\n }\n self.clients.claim();\n }());\n}\n\nself.addEventListener('activate', activate);\n\n\n\n💡 O exemplo acima foi extraido do service worker gerado e usa
\nself.context.enviroment.key
⚔ Aprenda Como fazer o deploy de uma aplicação Nullstack.
\n","description":"O objeto worker é um proxy no Contexto Nullstack disponível em ambos client e server e te dá controle granular do comportamento do seu PWA"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Contexto Service Worker - Nullstack","description":"O objeto worker é um proxy no Contexto Nullstack disponível em ambos client e server e te dá controle granular do comportamento do seu PWA"}} \ No newline at end of file diff --git a/docs/pt-br/sobre.html b/docs/pt-br/sobre.html deleted file mode 100644 index 42cdae49..00000000 --- a/docs/pt-br/sobre.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - -Ele foi criado tendo em mente os programadores acostumados a desenvolver sistemas inteiros sozinhos, mas é facilmente escalável para equipes pequenas ou mesmo grandes, desde que cada programador conheça o fluxo do recurso que deve desenvolver.
-Com a maioria das tecnologias usadas na web hoje em dia, o fluxo mais comum é algo assim:
-Note que tudo que você queria era mostrar algo a partir do banco de dados em uma visualização. Com o Nullstack, você só precisa se preocupar com a lógica. Todo o resto é Glue Code e o framework deve cuidar disso para você.
-Se você está acostumado a trabalhar em mais de um projeto ao mesmo tempo ou mesmo se por acaso tiver que dar manutenção esporádica em muitos de seus projetos antigos, você pode ter tropeçado neste cenário: você não se lembra exatamente onde em seu código está a lógica que você está tentando consertar ou melhorar.
-Você pode ter um gancho cujas dependências são variáveis locais inicializadas com um estado redux, que foi armazenado em algum ponto por uma ação declarada em algum lugar em seu código fonte e chamada sabe-se lá onde.
-Se tudo o que pertence a um único recurso estivesse no mesmo arquivo, talvez você não precisasse fazer engenharia reversa em seu próprio código toda vez que precisar atualizar ou corrigir algo.
-Colocar tudo em um único arquivo pode parecer confuso à primeira vista, mas lembre-se de que você é quem decide a granularidade dessa divisão.
-Um "recurso" pode ser um formulário de registro inteiro ou algo tão pequeno quanto um botão que faz algumas verificações antes de permitir que você envie esse formulário. Depende inteiramente de você e, como cada componente é tão completo quanto um recurso inteiro, você pode chamar esse botão ou até mesmo o formulário inteiro em outras páginas de seu aplicativo. Isso nos leva à Verdadeira componentização e reutilização de código.
-Os componentes do Nullstack são autossuficientes.
-A maioria dos frameworks são especializados em apenas uma camada do desenvolvimento. Ao exportar um componente Nullstack, todo o código necessário para rodar o recurso vai ficar junto, sem a necessidade de alocar as outras camadas separadamente.
-Como efeito colateral, aplicativos inteiros podem ser usados como componentes e montados em outros aplicativos como engines.
-À primeira vista, as classes podem parecer mais detalhadas do que os componentes funcionais. -Esta seção explicará os motivos que nos levam a favorecer as classes no desenvolvimento do Nullstack.
-As razões estão, na verdade, conectadas a alguns princípios básicos do Nullstack, sendo:
-Nós não queremos introduzir um “modo Nullstack” de fazer as coisas, queremos que se torne algo acessível a qualquer pessoa com algum conhecimento Javascript.
-Dito isso, o primeiro grande problema foi abordar o gerenciamento de estado de uma forma Javascript padrão. O suporte de componentes funcionais exigiria uma solução semelhante aos ganchos de React.js, que seriam considerados um maneirismo do framework.
-Uma vez que optamos pela imutabilidade como uma restrição do framework, podemos usar a forma nativa de definir variáveis simples. Isto remove a complexidade do gerenciamento de estados, o que foi responsável anteriormente pela necessidade de usar uma biblioteca de terceiros para o gerenciamento dos mesmos
-O Nullstack pega emprestado o conceito de “bateria incluída” do Ember.js, mas permite que você troque as baterias. Tudo que você precisa para fazer um aplicativo deve fazer parte do framework e ainda ser flexível.
-O framework deve fazer o trabalho pesado e o programador deveria focar na sua própria aplicação. -Por esse motivo tudo que você precisa fazer é declarar suas classes e deixar que o Nullstack instancie elas para você. -Desta forma, nos removemos o aspecto mais doloroso de lidar com classes enquanto mantemos todas as vantagens delas.
-Orientado a objetos vs. funcional não é um tópico novo e, ultimamente, o primeiro parece ter sido excluído da maioria dos frameworks, não deixando lugar para desenvolvedores que gostam desse padrão.
-É certo que as classes demoraram muito para serem padronizadas em Javascript e o atraso pode ter causado algumas implementações traumáticas ao longo do caminho.
-Embora a programação orientada a objetos possa não ser a melhor solução para todos os problemas, o Nullstack permite que você importe funções livremente e as use nos momentos em que você achar melhor.
-O contexto do Nullstack usa o padrão de injeção de dependência, o que significa que tudo o que você precisa pode ser solicitado do framework a partir da camada em que está a função.
-O contexto é um objeto com escopo horizontal que é injetado em todas as suas chamadas de função. A natureza não hierárquica desse padrão permite que você mova facilmente a lógica de seu componente conforme seu aplicativo cresce, enquanto ainda evita problemas com threading ou encher seu código-fonte com inúmeras declarações para a mesma coisa.
-Isso tem duas vantagens principais:
-Você vê as dependências de seu código em uma função, em vez de tê-los todos importados na parte superior do arquivo.
O framework é capaz de lhe dar informações mais precisas sobre o ambiente específico para essa chamada de função.
A aplicação gerada é suficiente para ser um PWA (Progressive Web App) sem pensar em boilerplates, e ainda mais, você é livre para substituir o comportamento padrão das funções.
-Um conceito emprestado do Ruby é a “felicidade do desenvolvedor”. O objetivo do Nullstack é facilitar a vida do desenvolvedor, simplificando tudo o que for possível sem esconder nada de você.
-Os primeiros desenvolvedores que queríamos deixar felizes somos nós mesmos. Fizemos o Nullstack porque nos divertimos no processo. Tudo começou como um protótipo simples em cima do React.js e nos empolgamos, tornando-o cada vez mais agradável para nós até que se tornou algo próprio.
-Esperamos que você goste de usar o Nullstack tanto quanto nós, porque é isso que mantém este projeto avançando.
-Ele foi criado tendo em mente os programadores acostumados a desenvolver sistemas inteiros sozinhos, mas é facilmente escalável para equipes pequenas ou mesmo grandes, desde que cada programador conheça o fluxo do recurso que deve desenvolver.
-Com a maioria das tecnologias usadas na web hoje em dia, o fluxo mais comum é algo assim:
-Note que tudo que você queria era mostrar algo a partir do banco de dados em uma visualização. Com o Nullstack, você só precisa se preocupar com a lógica. Todo o resto é Glue Code e o framework deve cuidar disso para você.
-Se você está acostumado a trabalhar em mais de um projeto ao mesmo tempo ou mesmo se por acaso tiver que dar manutenção esporádica em muitos de seus projetos antigos, você pode ter tropeçado neste cenário: você não se lembra exatamente onde em seu código está a lógica que você está tentando consertar ou melhorar.
-Você pode ter um gancho cujas dependências são variáveis locais inicializadas com um estado redux, que foi armazenado em algum ponto por uma ação declarada em algum lugar em seu código fonte e chamada sabe-se lá onde.
-Se tudo o que pertence a um único recurso estivesse no mesmo arquivo, talvez você não precisasse fazer engenharia reversa em seu próprio código toda vez que precisar atualizar ou corrigir algo.
-Colocar tudo em um único arquivo pode parecer confuso à primeira vista, mas lembre-se de que você é quem decide a granularidade dessa divisão.
-Um "recurso" pode ser um formulário de registro inteiro ou algo tão pequeno quanto um botão que faz algumas verificações antes de permitir que você envie esse formulário. Depende inteiramente de você e, como cada componente é tão completo quanto um recurso inteiro, você pode chamar esse botão ou até mesmo o formulário inteiro em outras páginas de seu aplicativo. Isso nos leva à Verdadeira componentização e reutilização de código.
-Os componentes do Nullstack são autossuficientes.
-A maioria dos frameworks são especializados em apenas uma camada do desenvolvimento. Ao exportar um componente Nullstack, todo o código necessário para rodar o recurso vai ficar junto, sem a necessidade de alocar as outras camadas separadamente.
-Como efeito colateral, aplicativos inteiros podem ser usados como componentes e montados em outros aplicativos como engines.
-À primeira vista, as classes podem parecer mais detalhadas do que os componentes funcionais. -Esta seção explicará os motivos que nos levam a favorecer as classes no desenvolvimento do Nullstack.
-As razões estão, na verdade, conectadas a alguns princípios básicos do Nullstack, sendo:
-Nós não queremos introduzir um “modo Nullstack” de fazer as coisas, queremos que se torne algo acessível a qualquer pessoa com algum conhecimento Javascript.
-Dito isso, o primeiro grande problema foi abordar o gerenciamento de estado de uma forma Javascript padrão. O suporte de componentes funcionais exigiria uma solução semelhante aos ganchos de React.js, que seriam considerados um maneirismo do framework.
-Uma vez que optamos pela imutabilidade como uma restrição do framework, podemos usar a forma nativa de definir variáveis simples. Isto remove a complexidade do gerenciamento de estados, o que foi responsável anteriormente pela necessidade de usar uma biblioteca de terceiros para o gerenciamento dos mesmos
-O Nullstack pega emprestado o conceito de “bateria incluída” do Ember.js, mas permite que você troque as baterias. Tudo que você precisa para fazer um aplicativo deve fazer parte do framework e ainda ser flexível.
-O framework deve fazer o trabalho pesado e o programador deveria focar na sua própria aplicação. -Por esse motivo tudo que você precisa fazer é declarar suas classes e deixar que o Nullstack instancie elas para você. -Desta forma, nos removemos o aspecto mais doloroso de lidar com classes enquanto mantemos todas as vantagens delas.
-Orientado a objetos vs. funcional não é um tópico novo e, ultimamente, o primeiro parece ter sido excluído da maioria dos frameworks, não deixando lugar para desenvolvedores que gostam desse padrão.
-É certo que as classes demoraram muito para serem padronizadas em Javascript e o atraso pode ter causado algumas implementações traumáticas ao longo do caminho.
-Embora a programação orientada a objetos possa não ser a melhor solução para todos os problemas, o Nullstack permite que você importe funções livremente e as use nos momentos em que você achar melhor.
-O contexto do Nullstack usa o padrão de injeção de dependência, o que significa que tudo o que você precisa pode ser solicitado do framework a partir da camada em que está a função.
-O contexto é um objeto com escopo horizontal que é injetado em todas as suas chamadas de função. A natureza não hierárquica desse padrão permite que você mova facilmente a lógica de seu componente conforme seu aplicativo cresce, enquanto ainda evita problemas com threading ou encher seu código-fonte com inúmeras declarações para a mesma coisa.
-Isso tem duas vantagens principais:
-Você vê as dependências de seu código em uma função, em vez de tê-los todos importados na parte superior do arquivo.
O framework é capaz de lhe dar informações mais precisas sobre o ambiente específico para essa chamada de função.
A aplicação gerada é suficiente para ser um PWA (Progressive Web App) sem pensar em boilerplates, e ainda mais, você é livre para substituir o comportamento padrão das funções.
-Um conceito emprestado do Ruby é a “felicidade do desenvolvedor”. O objetivo do Nullstack é facilitar a vida do desenvolvedor, simplificando tudo o que for possível sem esconder nada de você.
-Os primeiros desenvolvedores que queríamos deixar felizes somos nós mesmos. Fizemos o Nullstack porque nos divertimos no processo. Tudo começou como um protótipo simples em cima do React.js e nos empolgamos, tornando-o cada vez mais agradável para nós até que se tornou algo próprio.
-Esperamos que você goste de usar o Nullstack tanto quanto nós, porque é isso que mantém este projeto avançando.
-Ele foi criado tendo em mente os programadores acostumados a desenvolver sistemas inteiros sozinhos, mas é facilmente escalável para equipes pequenas ou mesmo grandes, desde que cada programador conheça o fluxo do recurso que deve desenvolver.
\nCom a maioria das tecnologias usadas na web hoje em dia, o fluxo mais comum é algo assim:
\nNote que tudo que você queria era mostrar algo a partir do banco de dados em uma visualização. Com o Nullstack, você só precisa se preocupar com a lógica. Todo o resto é Glue Code e o framework deve cuidar disso para você.
\nSe você está acostumado a trabalhar em mais de um projeto ao mesmo tempo ou mesmo se por acaso tiver que dar manutenção esporádica em muitos de seus projetos antigos, você pode ter tropeçado neste cenário: você não se lembra exatamente onde em seu código está a lógica que você está tentando consertar ou melhorar.
\nVocê pode ter um gancho cujas dependências são variáveis locais inicializadas com um estado redux, que foi armazenado em algum ponto por uma ação declarada em algum lugar em seu código fonte e chamada sabe-se lá onde.
\nSe tudo o que pertence a um único recurso estivesse no mesmo arquivo, talvez você não precisasse fazer engenharia reversa em seu próprio código toda vez que precisar atualizar ou corrigir algo.
\nColocar tudo em um único arquivo pode parecer confuso à primeira vista, mas lembre-se de que você é quem decide a granularidade dessa divisão.
\nUm "recurso" pode ser um formulário de registro inteiro ou algo tão pequeno quanto um botão que faz algumas verificações antes de permitir que você envie esse formulário. Depende inteiramente de você e, como cada componente é tão completo quanto um recurso inteiro, você pode chamar esse botão ou até mesmo o formulário inteiro em outras páginas de seu aplicativo. Isso nos leva à Verdadeira componentização e reutilização de código.
\nOs componentes do Nullstack são autossuficientes.
\nA maioria dos frameworks são especializados em apenas uma camada do desenvolvimento. Ao exportar um componente Nullstack, todo o código necessário para rodar o recurso vai ficar junto, sem a necessidade de alocar as outras camadas separadamente.
\nComo efeito colateral, aplicativos inteiros podem ser usados como componentes e montados em outros aplicativos como engines.
\nÀ primeira vista, as classes podem parecer mais detalhadas do que os componentes funcionais.\nEsta seção explicará os motivos que nos levam a favorecer as classes no desenvolvimento do Nullstack.
\nAs razões estão, na verdade, conectadas a alguns princípios básicos do Nullstack, sendo:
\nNós não queremos introduzir um “modo Nullstack” de fazer as coisas, queremos que se torne algo acessível a qualquer pessoa com algum conhecimento Javascript.
\nDito isso, o primeiro grande problema foi abordar o gerenciamento de estado de uma forma Javascript padrão. O suporte de componentes funcionais exigiria uma solução semelhante aos ganchos de React.js, que seriam considerados um maneirismo do framework.
\nUma vez que optamos pela imutabilidade como uma restrição do framework, podemos usar a forma nativa de definir variáveis simples. Isto remove a complexidade do gerenciamento de estados, o que foi responsável anteriormente pela necessidade de usar uma biblioteca de terceiros para o gerenciamento dos mesmos
\nO Nullstack pega emprestado o conceito de “bateria incluída” do Ember.js, mas permite que você troque as baterias. Tudo que você precisa para fazer um aplicativo deve fazer parte do framework e ainda ser flexível.
\nO framework deve fazer o trabalho pesado e o programador deveria focar na sua própria aplicação.\nPor esse motivo tudo que você precisa fazer é declarar suas classes e deixar que o Nullstack instancie elas para você.\nDesta forma, nos removemos o aspecto mais doloroso de lidar com classes enquanto mantemos todas as vantagens delas.
\nOrientado a objetos vs. funcional não é um tópico novo e, ultimamente, o primeiro parece ter sido excluído da maioria dos frameworks, não deixando lugar para desenvolvedores que gostam desse padrão.
\nÉ certo que as classes demoraram muito para serem padronizadas em Javascript e o atraso pode ter causado algumas implementações traumáticas ao longo do caminho.
\nEmbora a programação orientada a objetos possa não ser a melhor solução para todos os problemas, o Nullstack permite que você importe funções livremente e as use nos momentos em que você achar melhor.
\nO contexto do Nullstack usa o padrão de injeção de dependência, o que significa que tudo o que você precisa pode ser solicitado do framework a partir da camada em que está a função.
\nO contexto é um objeto com escopo horizontal que é injetado em todas as suas chamadas de função. A natureza não hierárquica desse padrão permite que você mova facilmente a lógica de seu componente conforme seu aplicativo cresce, enquanto ainda evita problemas com threading ou encher seu código-fonte com inúmeras declarações para a mesma coisa.
\nIsso tem duas vantagens principais:
\nVocê vê as dependências de seu código em uma função, em vez de tê-los todos importados na parte superior do arquivo.
O framework é capaz de lhe dar informações mais precisas sobre o ambiente específico para essa chamada de função.
A aplicação gerada é suficiente para ser um PWA (Progressive Web App) sem pensar em boilerplates, e ainda mais, você é livre para substituir o comportamento padrão das funções.
\nUm conceito emprestado do Ruby é a “felicidade do desenvolvedor”. O objetivo do Nullstack é facilitar a vida do desenvolvedor, simplificando tudo o que for possível sem esconder nada de você.
\nOs primeiros desenvolvedores que queríamos deixar felizes somos nós mesmos. Fizemos o Nullstack porque nos divertimos no processo. Tudo começou como um protótipo simples em cima do React.js e nos empolgamos, tornando-o cada vez mais agradável para nós até que se tornou algo próprio.
\nEsperamos que você goste de usar o Nullstack tanto quanto nós, porque é isso que mantém este projeto avançando.
\n","description":"O único propósito de Nullstack é simplificar o desenvolvimento, eliminando o Glue Code e permitindo-lhe se concentrar na lógica de sua aplicação."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Por quê criamos o Nullstack? - Nullstack","description":"O único propósito de Nullstack é simplificar o desenvolvimento, eliminando o Glue Code e permitindo-lhe se concentrar na lógica de sua aplicação."}} \ No newline at end of file diff --git "a/docs/pt-br/trabalhador-servi\303\247o.html" "b/docs/pt-br/trabalhador-servi\303\247o.html" deleted file mode 100644 index e64e45b7..00000000 --- "a/docs/pt-br/trabalhador-servi\303\247o.html" +++ /dev/null @@ -1,54 +0,0 @@ - - - - - -Talvez você queira aprender como criar uma pagina 404 com Nullstack?
-Se você está procurando por outra coisa, você deveria ler a documentação.
-Talvez você queira aprender como criar uma pagina 404 com Nullstack?
-Se você está procurando por outra coisa, você deveria ler a documentação.
-Talvez você queira aprender como criar uma pagina 404 com Nullstack?
\nSe você está procurando por outra coisa, você deveria ler a documentação.
\n","description":"Desculpe, essa não é a página que você está procurando","status":404},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":404,"title":"Página Não Encontrada - Nullstack","description":"Desculpe, essa não é a página que você está procurando"}} \ No newline at end of file diff --git a/docs/pt-br/vinculo-bidirecional.html b/docs/pt-br/vinculo-bidirecional.html deleted file mode 100644 index 4366e725..00000000 --- a/docs/pt-br/vinculo-bidirecional.html +++ /dev/null @@ -1,287 +0,0 @@ - - - - - -Big chunks of code in a progressive web application is dedicated to reacting to user input.
-The process of controlling user input can be broken into 3 tedious steps:
-The last step might include typecasting and other value treatments.
-This process in which you manually do all these steps is called one-way binding, it is the default in many frameworks, and is possible in Nullstack.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- string = '';
-
- updateString({event}) {
- this.string = event.target.value;
- }
-
- updateNumber({event}) {
- this.number = parseInt(event.target.value);
- }
-
- render() {
- return (
- <form>
- <input
- type="text"
- name="string"
- value={this.string}
- oninput={this.updateString}
- />
- <input
- type="number"
- name="number"
- value={this.number}
- oninput={this.updateNumber}
- />
- </form>
- )
- }
-
-}
-
-export default Form;
-
-Bind reduces drastically the amount of glue code you have to type in your application.
-You can shortcut setting a value, name, and event with the bind attribute.
--💡 Nullstack will simply replace
-bindwith thevalue,name, and event under the hood.
Bind will generate an event that automatically typecasts to the previous primitive type the value was.
-You can pass any variable to the bind as long as its parent object is mentioned.
import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- string = '';
-
- render() {
- return (
- <form>
- <input type="text" bind={this.string} />
- <input type="number" bind={this.number} />
- </form>
- )
- }
-
-}
-
-export default Form;
-
-The following events are set for each type of input:
-onclick for inputs with the checkbox typeoninput for other inputs and textareasonchange for anything elseYou can still declare an attribute with the same bound event.
-Events will not override the bound event, instead, it will be executed after bind mutates the variable.
-The new value will be merged into the function context.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- name = '';
-
- compare({value}) {
- this.name === value;
- }
-
- render() {
- return (
- <input bind={this.name} oninput={this.compare} />
- )
- }
-
-}
-
-export default Form;
-
-Bind can take a source attribute as well.
--💡 If you do not declare a source to the bind, Nullstack will inject a
-source={this}at transpile time in order to completely skip the runtime lookup process!
If you declare a source, bind must be a string with the name of the key that will be mutated.
The source will be merged into the context of events.
-import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- validate({source, params}) {
- if(!source.page) {
- params.page = '1';
- }
- }
-
- render({params}) {
- return (
- <input
- source={params}
- bind="page"
- oninput={this.validate}
- />
- )
- }
-
-}
-
-export default Paginator;
-
---💡 Binding by reference is possible because all binds are converted to the format above at transpile time.
-
Any object that responds to a key call with "[]" can be bound.
-The name attribute can be overwritten.
import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- boolean = true;
- character = 'a';
- text = 'aaaa';
-
- object = {count: 1};
- array = ['a', 'b', 'c'];
-
- render({params}) {
- return (
- <div>
- <input bind={this.number} />
- <textarea bind={this.text} />
- <select bind={this.character}>
- {this.array.map((character) => <option>{character}</option>)}
- </select>
- <select bind={this.boolean} name="boolean-select">
- <option value={true}>true</option>
- <option value={false}>false</option>
- </select>
- <input bind={this.boolean} type="checkbox" />
- <input bind={this.object.count} />
- {this.array.map((value, index) => (
- <input bind={this.array[index]} />
- ))}
- <input bind={params.page} />
- </div>
- )
- }
-
-}
-
-export default Form;
-
-You can use object events alongside bind normally.
The event will run after the variable is mutated.
-The event will share the bind source.
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- render({params}) {
- return (
- <input bind={params.filter} oninput={{page: 1}} />
- )
- }
-
-}
-
-export default Paginator;
-
-You can create your own bindable component by receiving the attributes that bind generates.
You must respond by calling onchange with a value key.
You can also merge any other keys you wish to send to the component user.
-class CurrencyInput extends Nullstack {
-
- parse({event, onchange}) {
- const normalized = event.target.value.replace(',', '').padStart(3, '0');
- const whole = (parseInt(normalized.slice(0,-2)) || 0).toString();
- const decimal = normalized.slice(normalized.length - 2);
- const value = parseFloat(whole+'.'+decimal);
- const bringsHappyness = value >= 1000000;
- onchange({value, bringsHappyness});
- }
-
- render({value, name}) {
- const formatted = value.toFixed(2).replace('.', ',');
- return <input name={name} value={formatted} oninput={this.parse} />
- }
-
-}
-
-import Nullstack from 'nullstack';
-import CurrencyInput from './CurrencyInput';
-
-class Form extends Nullstack {
-
- balance = 0;
-
- render() {
- return (
- <CurrencyInput bind={this.balance} />
- )
- }
-
-}
-
-export default Form;
-
---🎉 Congratulations!. You are done with the core concepts!
-
⚔ Learn about the application startup.
-Big chunks of code in a progressive web application is dedicated to reacting to user input.
-The process of controlling user input can be broken into 3 tedious steps:
-The last step might include typecasting and other value treatments.
-This process in which you manually do all these steps is called one-way binding, it is the default in many frameworks, and is possible in Nullstack.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- string = '';
-
- updateString({event}) {
- this.string = event.target.value;
- }
-
- updateNumber({event}) {
- this.number = parseInt(event.target.value);
- }
-
- render() {
- return (
- <form>
- <input
- type="text"
- name="string"
- value={this.string}
- oninput={this.updateString}
- />
- <input
- type="number"
- name="number"
- value={this.number}
- oninput={this.updateNumber}
- />
- </form>
- )
- }
-
-}
-
-export default Form;
-
-Bind reduces drastically the amount of glue code you have to type in your application.
-You can shortcut setting a value, name, and event with the bind attribute.
--💡 Nullstack will simply replace
-bindwith thevalue,name, and event under the hood.
Bind will generate an event that automatically typecasts to the previous primitive type the value was.
-You can pass any variable to the bind as long as its parent object is mentioned.
import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- string = '';
-
- render() {
- return (
- <form>
- <input type="text" bind={this.string} />
- <input type="number" bind={this.number} />
- </form>
- )
- }
-
-}
-
-export default Form;
-
-The following events are set for each type of input:
-onclick for inputs with the checkbox typeoninput for other inputs and textareasonchange for anything elseYou can still declare an attribute with the same bound event.
-Events will not override the bound event, instead, it will be executed after bind mutates the variable.
-The new value will be merged into the function context.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- name = '';
-
- compare({value}) {
- this.name === value;
- }
-
- render() {
- return (
- <input bind={this.name} oninput={this.compare} />
- )
- }
-
-}
-
-export default Form;
-
-Bind can take a source attribute as well.
--💡 If you do not declare a source to the bind, Nullstack will inject a
-source={this}at transpile time in order to completely skip the runtime lookup process!
If you declare a source, bind must be a string with the name of the key that will be mutated.
The source will be merged into the context of events.
-import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- validate({source, params}) {
- if(!source.page) {
- params.page = '1';
- }
- }
-
- render({params}) {
- return (
- <input
- source={params}
- bind="page"
- oninput={this.validate}
- />
- )
- }
-
-}
-
-export default Paginator;
-
---💡 Binding by reference is possible because all binds are converted to the format above at transpile time.
-
Any object that responds to a key call with "[]" can be bound.
-The name attribute can be overwritten.
import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- boolean = true;
- character = 'a';
- text = 'aaaa';
-
- object = {count: 1};
- array = ['a', 'b', 'c'];
-
- render({params}) {
- return (
- <div>
- <input bind={this.number} />
- <textarea bind={this.text} />
- <select bind={this.character}>
- {this.array.map((character) => <option>{character}</option>)}
- </select>
- <select bind={this.boolean} name="boolean-select">
- <option value={true}>true</option>
- <option value={false}>false</option>
- </select>
- <input bind={this.boolean} type="checkbox" />
- <input bind={this.object.count} />
- {this.array.map((value, index) => (
- <input bind={this.array[index]} />
- ))}
- <input bind={params.page} />
- </div>
- )
- }
-
-}
-
-export default Form;
-
-You can use object events alongside bind normally.
The event will run after the variable is mutated.
-The event will share the bind source.
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- render({params}) {
- return (
- <input bind={params.filter} oninput={{page: 1}} />
- )
- }
-
-}
-
-export default Paginator;
-
-You can create your own bindable component by receiving the attributes that bind generates.
You must respond by calling onchange with a value key.
You can also merge any other keys you wish to send to the component user.
-class CurrencyInput extends Nullstack {
-
- parse({event, onchange}) {
- const normalized = event.target.value.replace(',', '').padStart(3, '0');
- const whole = (parseInt(normalized.slice(0,-2)) || 0).toString();
- const decimal = normalized.slice(normalized.length - 2);
- const value = parseFloat(whole+'.'+decimal);
- const bringsHappyness = value >= 1000000;
- onchange({value, bringsHappyness});
- }
-
- render({value, name}) {
- const formatted = value.toFixed(2).replace('.', ',');
- return <input name={name} value={formatted} oninput={this.parse} />
- }
-
-}
-
-import Nullstack from 'nullstack';
-import CurrencyInput from './CurrencyInput';
-
-class Form extends Nullstack {
-
- balance = 0;
-
- render() {
- return (
- <CurrencyInput bind={this.balance} />
- )
- }
-
-}
-
-export default Form;
-
---🎉 Congratulations!. You are done with the core concepts!
-
⚔ Learn about the application startup.
-Big chunks of code in a progressive web application is dedicated to reacting to user input.
\nThe process of controlling user input can be broken into 3 tedious steps:
\nThe last step might include typecasting and other value treatments.
\nThis process in which you manually do all these steps is called one-way binding, it is the default in many frameworks, and is possible in Nullstack.
\nimport Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n number = 1;\n string = '';\n\n updateString({event}) {\n this.string = event.target.value;\n }\n\n updateNumber({event}) {\n this.number = parseInt(event.target.value);\n }\n \n render() {\n return (\n <form>\n <input\n type=\"text\"\n name=\"string\"\n value={this.string}\n oninput={this.updateString}\n />\n <input\n type=\"number\"\n name=\"number\"\n value={this.number}\n oninput={this.updateNumber}\n />\n </form>\n )\n }\n\n}\n\nexport default Form;\n\nBind reduces drastically the amount of glue code you have to type in your application.
\nYou can shortcut setting a value, name, and event with the bind attribute.
\n\n💡 Nullstack will simply replace
\nbindwith thevalue,name, and event under the hood.
Bind will generate an event that automatically typecasts to the previous primitive type the value was.
\nYou can pass any variable to the bind as long as its parent object is mentioned.
import Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n number = 1;\n string = '';\n \n render() {\n return (\n <form>\n <input type=\"text\" bind={this.string} />\n <input type=\"number\" bind={this.number} />\n </form>\n )\n }\n\n}\n\nexport default Form;\n\nThe following events are set for each type of input:
\nonclick for inputs with the checkbox typeoninput for other inputs and textareasonchange for anything elseYou can still declare an attribute with the same bound event.
\nEvents will not override the bound event, instead, it will be executed after bind mutates the variable.
\nThe new value will be merged into the function context.
\nimport Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n name = '';\n\n compare({value}) {\n this.name === value;\n }\n \n render() {\n return (\n <input bind={this.name} oninput={this.compare} />\n )\n }\n\n}\n\nexport default Form;\n\nBind can take a source attribute as well.
\n\n💡 If you do not declare a source to the bind, Nullstack will inject a
\nsource={this}at transpile time in order to completely skip the runtime lookup process!
If you declare a source, bind must be a string with the name of the key that will be mutated.
The source will be merged into the context of events.
\nimport Nullstack from 'nullstack';\n\nclass Paginator extends Nullstack {\n\n validate({source, params}) {\n if(!source.page) {\n params.page = '1';\n }\n }\n\n render({params}) {\n return (\n <input \n source={params}\n bind=\"page\"\n oninput={this.validate}\n />\n )\n }\n\n}\n\nexport default Paginator;\n\n\n\n💡 Binding by reference is possible because all binds are converted to the format above at transpile time.
\n
Any object that responds to a key call with "[]" can be bound.
\nThe name attribute can be overwritten.
import Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n number = 1;\n boolean = true;\n character = 'a';\n text = 'aaaa';\n \n object = {count: 1};\n array = ['a', 'b', 'c'];\n\n render({params}) {\n return (\n <div>\n <input bind={this.number} />\n <textarea bind={this.text} />\n <select bind={this.character}>\n {this.array.map((character) => <option>{character}</option>)}\n </select>\n <select bind={this.boolean} name=\"boolean-select\">\n <option value={true}>true</option>\n <option value={false}>false</option>\n </select>\n <input bind={this.boolean} type=\"checkbox\" />\n <input bind={this.object.count} />\n {this.array.map((value, index) => (\n <input bind={this.array[index]} />\n ))}\n <input bind={params.page} />\n </div>\n )\n }\n\n}\n\nexport default Form;\n\nYou can use object events alongside bind normally.
The event will run after the variable is mutated.
\nThe event will share the bind source.
import Nullstack from 'nullstack';\n\nclass Paginator extends Nullstack {\n\n render({params}) {\n return (\n <input bind={params.filter} oninput={{page: 1}} />\n )\n }\n\n}\n\nexport default Paginator;\n\nYou can create your own bindable component by receiving the attributes that bind generates.
You must respond by calling onchange with a value key.
You can also merge any other keys you wish to send to the component user.
\nclass CurrencyInput extends Nullstack {\n\n parse({event, onchange}) {\n const normalized = event.target.value.replace(',', '').padStart(3, '0');\n const whole = (parseInt(normalized.slice(0,-2)) || 0).toString();\n const decimal = normalized.slice(normalized.length - 2);\n const value = parseFloat(whole+'.'+decimal);\n const bringsHappyness = value >= 1000000;\n onchange({value, bringsHappyness});\n }\n\n render({value, name}) {\n const formatted = value.toFixed(2).replace('.', ',');\n return <input name={name} value={formatted} oninput={this.parse} />\n }\n\n}\n\nimport Nullstack from 'nullstack';\nimport CurrencyInput from './CurrencyInput';\n\nclass Form extends Nullstack {\n\n balance = 0;\n\n render() {\n return (\n <CurrencyInput bind={this.balance} />\n )\n }\n\n}\n\nexport default Form;\n\n\n\n🎉 Congratulations!. You are done with the core concepts!
\n
⚔ Learn about the application startup.
\n","description":"Bind reduces drastically the amount of glue code you have to type in your application."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"pt-BR","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Waifu oficial do Nullstack"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Two-Way Binding - Nullstack","description":"Bind reduces drastically the amount of glue code you have to type in your application."}} \ No newline at end of file diff --git a/docs/pt-br/waifu.html b/docs/pt-br/waifu.html deleted file mode 100644 index f781243a..00000000 --- a/docs/pt-br/waifu.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - -
Waifu oficial do Nullstack
Uma doce e tímida waifu perfeita, está sempre hiperfocada em seus estudos, mas de alguma forma distraída ao mesmo tempo.
Está sempre alegre... até que ela tenha que enfrentar código grudento ou ver um post dizendo que tecnologia ela deve usar.

Waifu oficial do Nullstack
Uma doce e tímida waifu perfeita, está sempre hiperfocada em seus estudos, mas de alguma forma distraída ao mesmo tempo.
Está sempre alegre... até que ela tenha que enfrentar código grudento ou ver um post dizendo que tecnologia ela deve usar.
The simplest component you can make is a renderable component.
-Renderable components are very similar to web components, they give you the ability to create new HTML tags that shortcut a group of other HTML tags.
-Create a file in your src folder with the name of your component and the njs extension.
-In this example it is going to be called HelloWorld.njs.
-All you have to do is to import Nullstack or any of its subclasses and extend your class from it, define an instance method called render that returns any JSX, and export the component.
---✨ Install the official Nullstack VSCode Extension to generate classes with a snippet.
-
import Nullstack from 'nullstack';
-
-class HelloWorld extends Nullstack {
-
- render() {
- return (
- <div> Hello World </div>
- )
- }
-
-}
-
-export default HelloWorld;
-
-The code above is just declaring the component, you still have to use it.
-Importing the component in your application gives you the ability to use a new tag in your render.
-This tag will be replaced with whatever you returned in your component render.
-import Nullstack from 'nullstack';
-
-import './Application.scss';
-
-import HelloWorld from './HelloWorld';
-
-class Application extends Nullstack {
-
- // ...
-
- render({page}) {
- return (
- <main>
- <h1> {page.title} </h1>
- <a href="https://nullstack.app/documentation" target="_blank"> Read the documentation </a>
- <HelloWorld />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Nullstack JSX deviates a little from the spec.
-You can use the normal HTML attributes like class and for directly.
<label for="input" class="dont-label-me"> I am a label </label>
-
-If you want to skip rendering the component at all you can simply return false from the render.
import Nullstack from 'nullstack';
-
-class Headless extends Nullstack {
-
- render() {
- return false;
- }
-
-}
-
-export default Headless;
-
-This will allocate DOM space for when you decide to render markup there.
-This is also useful for conditional rendering.
-If all you want to do is to generate an invisible component you can skip defining the render method at all.
-Instead of creating a new component just to organize code-splitting, you can create an inner component.
-Inner components are any method that the name starts with render followed by an uppercase character.
Inner components share the same instance and scope as the main component, therefore, are very convenient to avoid problems like props drilling.
-To invoke the inner component use a JSX tag with the method name without the render prefix.
import Nullstack from 'nullstack';
-
-class Post extends Nullstack {
-
- renderArticle() {
- return (
- <article> Content </article>
- )
- }
-
- renderAside() {
- return (
- <aside> Related content </aside>
- )
- }
-
- render() {
- return (
- <div>
- <Article />
- <Aside />
- </div>
- )
- }
-
-}
-
-export default HelloWorld;
-
---💡 Nullstack will inject a constant reference to the function at transpile time in order to completely skip the runtime lookup process!
-
Attributes can be assigned as a boolean.
-When the value is false the attribute will not be rendered at all.
When the value is true it will be rendered as a boolean attribute without a string value.
<button disabled={false}> Button </button>
-
-You can shortcut attributes when you know the value will always be true.
-<button disabled> Button </button>
-
---✨ Learn more about attributes.
-
If you need to decide the tag name at runtime, you can use the element tag and set the tag attribute conditionally.
-<element tag={!!link ? 'a' : 'span'} href={link || false}>
- some arbitrary text
-</element>
-
-When the tag attribute is omitted, Nullstack will default to a div.
SVG can be used as if it were any regular HTML tag.
-You can manipulate the SVG using attributes and events normally.
-<svg height={this.size} viewBox="0 0 100 100">
- <circle cx="50" cy="50" r="40" onclick={this.grow} />
-</svg>
-
---✨ Learn more about events.
-
Your component can be invoked passing a block of content.
-<Header>
- <h1> Hello World </h1>
-</Header>
-
-This doesn't automatically render the block since it wouldn't know where to place it.
-You can destructure the children on the render method and place it in your markup.
-import Nullstack from 'nullstack';
-
-class Header extends Nullstack {
-
- render({children}) {
- return (
- <div>{children}</div>
- )
- }
-
-}
-
-export default Header;
-
---✨ This is possible because the
-childrenkey is part of the instance context.
You can map over lists without declaring a key.
Lists that may change length must be wrapped in a parent element just for them.
-<ul>
- {list.map((item) => <li>{item.name}</li>)}
-</ul>
-
-You can emulate a fixed-size list by returning false instead of an element to reserve dom space.
{list.map((item) => (
- item.visible ? <div>{item.name}</div> : false
-)}
-
-It's a nice practice to use inner components combined with lists to clean up your code.
-import Nullstack from 'nullstack';
-
-class List extends Nullstack {
-
- items = [
- {visible: true, number: 1},
- {visible: false, number: 2},
- {visible: true, number: 3}
- ]
-
- renderItem({visible, number}) {
- if(!visible) return false;
- return (
- <li> {number} </li>
- )
- }
-
- render() {
- return (
- <ul>
- {this.items.map((item) => <Item {...item} />)}
- </ul>
- )
- }
-
-}
-
-export default List;
-
---✨ Sometimes you will notice keys in the map. Learn more about the instance key.
-
You can set the inner HTML of an element with the html attribute.
Links inside the HTML string will be replaced with routable anchors.
-import Nullstack from 'nullstack';
-
-class Post extends Nullstack {
-
- content = `
- <h1> This is a Post </h1>
- <a href="/other-post">
- Check this other post
- </a>
- `;
-
- render() {
- return (
- <article html={this.content} />
- )
- }
-
-}
-
-export default Post;
-
---🔥 Be careful! When using user-generated HTML you are in risk of script injection
-
Renderable components can render inside the head tag an unlimited number of times at any depth of the application.
The head tag will only be updated during the server-side rendering process and changes will be ignored after the hydration process.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <div>
- <head>
- <link rel="preconnect" href="https://www.googletagmanager.com" />
- </head>
- </div>
- <head>
- <link rel="preload" href="/roboto-v20-latin-300.woff2" as="font" type="font/woff2" crossorigin />
- <link rel="preload" href="/crete-round-v9-latin-regular.woff2" as="font" type="font/woff2" crossorigin />
- </head>
- </main>
- )
- }
-
-}
-
-export default Application;
-
---🔥 You should not use the
-headtag to update metatags that Nullstack already controls
⚔ Add state to your component using stateful components.
-The simplest component you can make is a renderable component.
-Renderable components are very similar to web components, they give you the ability to create new HTML tags that shortcut a group of other HTML tags.
-Create a file in your src folder with the name of your component and the njs extension.
-In this example it is going to be called HelloWorld.njs.
-All you have to do is to import Nullstack or any of its subclasses and extend your class from it, define an instance method called render that returns any JSX, and export the component.
---✨ Install the official Nullstack VSCode Extension to generate classes with a snippet.
-
import Nullstack from 'nullstack';
-
-class HelloWorld extends Nullstack {
-
- render() {
- return (
- <div> Hello World </div>
- )
- }
-
-}
-
-export default HelloWorld;
-
-The code above is just declaring the component, you still have to use it.
-Importing the component in your application gives you the ability to use a new tag in your render.
-This tag will be replaced with whatever you returned in your component render.
-import Nullstack from 'nullstack';
-
-import './Application.scss';
-
-import HelloWorld from './HelloWorld';
-
-class Application extends Nullstack {
-
- // ...
-
- render({page}) {
- return (
- <main>
- <h1> {page.title} </h1>
- <a href="https://nullstack.app/documentation" target="_blank"> Read the documentation </a>
- <HelloWorld />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Nullstack JSX deviates a little from the spec.
-You can use the normal HTML attributes like class and for directly.
<label for="input" class="dont-label-me"> I am a label </label>
-
-If you want to skip rendering the component at all you can simply return false from the render.
import Nullstack from 'nullstack';
-
-class Headless extends Nullstack {
-
- render() {
- return false;
- }
-
-}
-
-export default Headless;
-
-This will allocate DOM space for when you decide to render markup there.
-This is also useful for conditional rendering.
-If all you want to do is to generate an invisible component you can skip defining the render method at all.
-Instead of creating a new component just to organize code-splitting, you can create an inner component.
-Inner components are any method that the name starts with render followed by an uppercase character.
Inner components share the same instance and scope as the main component, therefore, are very convenient to avoid problems like props drilling.
-To invoke the inner component use a JSX tag with the method name without the render prefix.
import Nullstack from 'nullstack';
-
-class Post extends Nullstack {
-
- renderArticle() {
- return (
- <article> Content </article>
- )
- }
-
- renderAside() {
- return (
- <aside> Related content </aside>
- )
- }
-
- render() {
- return (
- <div>
- <Article />
- <Aside />
- </div>
- )
- }
-
-}
-
-export default HelloWorld;
-
---💡 Nullstack will inject a constant reference to the function at transpile time in order to completely skip the runtime lookup process!
-
Attributes can be assigned as a boolean.
-When the value is false the attribute will not be rendered at all.
When the value is true it will be rendered as a boolean attribute without a string value.
<button disabled={false}> Button </button>
-
-You can shortcut attributes when you know the value will always be true.
-<button disabled> Button </button>
-
---✨ Learn more about attributes.
-
If you need to decide the tag name at runtime, you can use the element tag and set the tag attribute conditionally.
-<element tag={!!link ? 'a' : 'span'} href={link || false}>
- some arbitrary text
-</element>
-
-When the tag attribute is omitted, Nullstack will default to a div.
SVG can be used as if it were any regular HTML tag.
-You can manipulate the SVG using attributes and events normally.
-<svg height={this.size} viewBox="0 0 100 100">
- <circle cx="50" cy="50" r="40" onclick={this.grow} />
-</svg>
-
---✨ Learn more about events.
-
Your component can be invoked passing a block of content.
-<Header>
- <h1> Hello World </h1>
-</Header>
-
-This doesn't automatically render the block since it wouldn't know where to place it.
-You can destructure the children on the render method and place it in your markup.
-import Nullstack from 'nullstack';
-
-class Header extends Nullstack {
-
- render({children}) {
- return (
- <div>{children}</div>
- )
- }
-
-}
-
-export default Header;
-
---✨ This is possible because the
-childrenkey is part of the instance context.
You can map over lists without declaring a key.
Lists that may change length must be wrapped in a parent element just for them.
-<ul>
- {list.map((item) => <li>{item.name}</li>)}
-</ul>
-
-You can emulate a fixed-size list by returning false instead of an element to reserve dom space.
{list.map((item) => (
- item.visible ? <div>{item.name}</div> : false
-)}
-
-It's a nice practice to use inner components combined with lists to clean up your code.
-import Nullstack from 'nullstack';
-
-class List extends Nullstack {
-
- items = [
- {visible: true, number: 1},
- {visible: false, number: 2},
- {visible: true, number: 3}
- ]
-
- renderItem({visible, number}) {
- if(!visible) return false;
- return (
- <li> {number} </li>
- )
- }
-
- render() {
- return (
- <ul>
- {this.items.map((item) => <Item {...item} />)}
- </ul>
- )
- }
-
-}
-
-export default List;
-
---✨ Sometimes you will notice keys in the map. Learn more about the instance key.
-
You can set the inner HTML of an element with the html attribute.
Links inside the HTML string will be replaced with routable anchors.
-import Nullstack from 'nullstack';
-
-class Post extends Nullstack {
-
- content = `
- <h1> This is a Post </h1>
- <a href="/other-post">
- Check this other post
- </a>
- `;
-
- render() {
- return (
- <article html={this.content} />
- )
- }
-
-}
-
-export default Post;
-
---🔥 Be careful! When using user-generated HTML you are in risk of script injection
-
Renderable components can render inside the head tag an unlimited number of times at any depth of the application.
The head tag will only be updated during the server-side rendering process and changes will be ignored after the hydration process.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- // ...
-
- render() {
- return (
- <main>
- <div>
- <head>
- <link rel="preconnect" href="https://www.googletagmanager.com" />
- </head>
- </div>
- <head>
- <link rel="preload" href="/roboto-v20-latin-300.woff2" as="font" type="font/woff2" crossorigin />
- <link rel="preload" href="/crete-round-v9-latin-regular.woff2" as="font" type="font/woff2" crossorigin />
- </head>
- </main>
- )
- }
-
-}
-
-export default Application;
-
---🔥 You should not use the
-headtag to update metatags that Nullstack already controls
⚔ Add state to your component using stateful components.
-The simplest component you can make is a renderable component.
\nRenderable components are very similar to web components, they give you the ability to create new HTML tags that shortcut a group of other HTML tags.
\nCreate a file in your src folder with the name of your component and the njs extension.
\nIn this example it is going to be called HelloWorld.njs.
\nAll you have to do is to import Nullstack or any of its subclasses and extend your class from it, define an instance method called render that returns any JSX, and export the component.
\n\n\n✨ Install the official Nullstack VSCode Extension to generate classes with a snippet.
\n
import Nullstack from 'nullstack';\n\nclass HelloWorld extends Nullstack {\n \n render() {\n return (\n <div> Hello World </div>\n )\n }\n\n}\n\nexport default HelloWorld;\n\nThe code above is just declaring the component, you still have to use it.
\nImporting the component in your application gives you the ability to use a new tag in your render.
\nThis tag will be replaced with whatever you returned in your component render.
\nimport Nullstack from 'nullstack';\n\nimport './Application.scss';\n\nimport HelloWorld from './HelloWorld';\n\nclass Application extends Nullstack {\n\n // ...\n\n render({page}) {\n return (\n <main>\n <h1> {page.title} </h1>\n <a href=\"https://nullstack.app/documentation\" target=\"_blank\"> Read the documentation </a>\n <HelloWorld />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nNullstack JSX deviates a little from the spec.
\nYou can use the normal HTML attributes like class and for directly.
<label for=\"input\" class=\"dont-label-me\"> I am a label </label>\n\nIf you want to skip rendering the component at all you can simply return false from the render.
import Nullstack from 'nullstack';\n\nclass Headless extends Nullstack {\n \n render() {\n return false;\n }\n\n}\n\nexport default Headless;\n\nThis will allocate DOM space for when you decide to render markup there.
\nThis is also useful for conditional rendering.
\nIf all you want to do is to generate an invisible component you can skip defining the render method at all.
\nInstead of creating a new component just to organize code-splitting, you can create an inner component.
\nInner components are any method that the name starts with render followed by an uppercase character.
Inner components share the same instance and scope as the main component, therefore, are very convenient to avoid problems like props drilling.
\nTo invoke the inner component use a JSX tag with the method name without the render prefix.
import Nullstack from 'nullstack';\n\nclass Post extends Nullstack {\n\n renderArticle() {\n return (\n <article> Content </article>\n )\n }\n\n renderAside() {\n return (\n <aside> Related content </aside>\n )\n }\n \n render() {\n return (\n <div>\n <Article />\n <Aside />\n </div>\n )\n }\n\n}\n\nexport default HelloWorld;\n\n\n\n💡 Nullstack will inject a constant reference to the function at transpile time in order to completely skip the runtime lookup process!
\n
Attributes can be assigned as a boolean.
\nWhen the value is false the attribute will not be rendered at all.
When the value is true it will be rendered as a boolean attribute without a string value.
<button disabled={false}> Button </button>\n\nYou can shortcut attributes when you know the value will always be true.
\n<button disabled> Button </button>\n\n\n\n✨ Learn more about attributes.
\n
If you need to decide the tag name at runtime, you can use the element tag and set the tag attribute conditionally.
\n<element tag={!!link ? 'a' : 'span'} href={link || false}>\n some arbitrary text\n</element>\n\nWhen the tag attribute is omitted, Nullstack will default to a div.
SVG can be used as if it were any regular HTML tag.
\nYou can manipulate the SVG using attributes and events normally.
\n<svg height={this.size} viewBox=\"0 0 100 100\">\n <circle cx=\"50\" cy=\"50\" r=\"40\" onclick={this.grow} />\n</svg> \n\n\n\n✨ Learn more about events.
\n
Your component can be invoked passing a block of content.
\n<Header> \n <h1> Hello World </h1>\n</Header>\n\nThis doesn't automatically render the block since it wouldn't know where to place it.
\nYou can destructure the children on the render method and place it in your markup.
\nimport Nullstack from 'nullstack';\n\nclass Header extends Nullstack {\n \n render({children}) {\n return (\n <div>{children}</div>\n )\n }\n\n}\n\nexport default Header;\n\n\n\n✨ This is possible because the
\nchildrenkey is part of the instance context.
You can map over lists without declaring a key.
Lists that may change length must be wrapped in a parent element just for them.
\n<ul>\n {list.map((item) => <li>{item.name}</li>)}\n</ul>\n\nYou can emulate a fixed-size list by returning false instead of an element to reserve dom space.
{list.map((item) => (\n item.visible ? <div>{item.name}</div> : false\n)}\n\nIt's a nice practice to use inner components combined with lists to clean up your code.
\nimport Nullstack from 'nullstack';\n\nclass List extends Nullstack {\n\n items = [\n {visible: true, number: 1},\n {visible: false, number: 2},\n {visible: true, number: 3}\n ]\n\n renderItem({visible, number}) {\n if(!visible) return false;\n return (\n <li> {number} </li>\n )\n }\n \n render() {\n return (\n <ul>\n {this.items.map((item) => <Item {...item} />)}\n </ul>\n )\n }\n\n}\n\nexport default List;\n\n\n\n✨ Sometimes you will notice keys in the map. Learn more about the instance key.
\n
You can set the inner HTML of an element with the html attribute.
Links inside the HTML string will be replaced with routable anchors.
\nimport Nullstack from 'nullstack';\n\nclass Post extends Nullstack {\n\n content = `\n <h1> This is a Post </h1>\n <a href=\"/other-post\">\n Check this other post\n </a>\n `;\n \n render() {\n return (\n <article html={this.content} />\n )\n }\n\n}\n\nexport default Post;\n\n\n\n🔥 Be careful! When using user-generated HTML you are in risk of script injection
\n
Renderable components can render inside the head tag an unlimited number of times at any depth of the application.
The head tag will only be updated during the server-side rendering process and changes will be ignored after the hydration process.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n // ...\n\n render() {\n return (\n <main>\n <div>\n <head>\n <link rel=\"preconnect\" href=\"https://www.googletagmanager.com\" />\n </head>\n </div>\n <head>\n <link rel=\"preload\" href=\"/roboto-v20-latin-300.woff2\" as=\"font\" type=\"font/woff2\" crossorigin />\n <link rel=\"preload\" href=\"/crete-round-v9-latin-regular.woff2\" as=\"font\" type=\"font/woff2\" crossorigin />\n </head>\n </main>\n )\n }\n\n}\n\nexport default Application;\n\n\n\n🔥 You should not use the
\nheadtag to update metatags that Nullstack already controls
⚔ Add state to your component using stateful components.
\n","description":"Renderable components are very similar to web components they give you the ability to create new HTML tags that shortcut a group of other HTML tags"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Renderable Components - Nullstack","description":"Renderable components are very similar to web components they give you the ability to create new HTML tags that shortcut a group of other HTML tags"}} \ No newline at end of file diff --git a/docs/roboto-v20-latin-300.woff2 b/docs/roboto-v20-latin-300.woff2 deleted file mode 100644 index ef8c8836..00000000 Binary files a/docs/roboto-v20-latin-300.woff2 and /dev/null differ diff --git a/docs/roboto-v20-latin-500.woff2 b/docs/roboto-v20-latin-500.woff2 deleted file mode 100644 index 6362d7f6..00000000 Binary files a/docs/roboto-v20-latin-500.woff2 and /dev/null differ diff --git a/docs/robots.txt b/docs/robots.txt deleted file mode 100644 index 95a840fc..00000000 --- a/docs/robots.txt +++ /dev/null @@ -1,3 +0,0 @@ -User-Agent: * -Allow: / -Sitemap: https://nullstack.app/sitemap.xml \ No newline at end of file diff --git a/docs/routes-and-params.html b/docs/routes-and-params.html deleted file mode 100644 index a906c457..00000000 --- a/docs/routes-and-params.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - -Nullstack has built-in routes, it would make no sense otherwise since web applications are expected to have hyperlinks.
-Any tag can receive a route attribute, be it a component, inner component, or simple HTML tag.
import Nullstack from 'nullstack';
-import Page from './Page';
-
-class Application extends Nullstack {
-
- renderHome() {
- return (
- <section> Home </section>
- )
- }
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <Page route="/page" />
- <abbr route="/abbreviations"> Abbreviations </abbr>
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Links on Nullstack are simple a tags with the href value starting with "/".
<a href="/page/about"> About Page </a>
-
---💡 On the client side the click event will push history without reloading the page.
-
--✨ You can still assign your own click event to the tag without losing the framework behavior.
-
The params key is an object proxy injected into every client instance.
Each query string param is mapped to this object.
-By default any key you request from this object will return a string.
-If the value is undefined it will return an empty string.
If the value is true or false it will return a boolean instead.
--🐱💻 Bellow an exemple that visits "/books?expanded=true&page=2":
-
import Nullstack from 'nullstack';
-
-class Books extends Nullstack {
-
- async initiate({params}) {
- if(params.expanded) {
- const page = parseInt(params.page) || 1;
- this.books = await this.getBooks({page});
- }
- }
-
-}
-
-export default Books;
-
-Assigning to a params key will cause a redirect to the route with updated params.
-When you assign to a param, the value will be converted to JSON before being set.
---💡 Redirects work in batches, so there is no performance loss in multiple assignments.
-
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- handleClick({params}) {
- params.filter = '';
- params.page = 1;
- }
-
-}
-
-export default Paginator;
-
-Assigning an empty string to a param will remove it from the url.
-Part of the route can be an expression started with ":" followed by a param name.
-This value will be matched against any string in the same directory position.
-The value of the string in the URL will be assigned to the context params and functions below this point in the hierarchy will have access to the new key.
---🐱💻 Bellow an example that visits "/category/suspense?page=2":
-
import Nullstack from 'nullstack';
-
-class Books extends Nullstack {
-
- async initiate({params}) {
- const page = parseInt(params.page) || 1;
- const category = params.slug;
- this.books = await this.getBooks({category, page});
- }
-
-}
-
-export default Books;
-
-import Nullstack from 'nullstack';
-import Books from './Books';
-
-class Application extends Nullstack {
-
- render() {
- <main>
- <Books route="/category/:slug">
- </main>
- }
-
-}
-
-export default Application;
-
-When a dynamic segment is changed, as for example moving from "/category/suspense" to "/category/comedy", the component will be terminated and a new instance will be created.
-Changing a query param will not re-instantiate the component.
-Children of the component will not be re-instantiated automatically, you can set the same route to the children or do it manually if you desire this behavior.
---💡 The behavior mentioned above solves many of the problems you have to normally deal with manually.
-
Wildcards are routes declared with "*" as the attribute value.
-These routes will match anything if nothing above it matches the requested URL.
-import Nullstack from 'nullstack';
-import Home from './Home';
-
-class Application extends Nullstack {
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <div route="*"> Wildcard </div>
- </main>
- )
- }
-
-}
-
-Wildcards can be prefixed with a segment.
---✨ this is especially useful for engines that can be mounted in your application.
-
import Nullstack from 'nullstack';
-import Home from './Home';
-import BlogEngine from './BlogEngine';
-
-class Application extends Nullstack {
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <BlogEngine route="/blog/*" />
- </main>
- )
- }
-
-}
-
-The router key is an object proxy injected into every client instance.
The router has two keys:
urlpathThe url key returns everything after the domain including the path and the query params as a string.
The path key returns only the path without query params.
--💡 Both keys above automatically remove the trailing slash for convenience.
-
Assigning to url or path will cause a redirect.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- prepare({router}) {
- if(router.path == '/') {
- router.path = '/dashboard';
- }
- }
-
-}
-
---💡 Under the hood
-atags withparamsuse therouter.
Updating router.url or router.path will raise a custom event.
import Nullstack from 'nullstack';
-
-class Analytics extends Nullstack {
-
- hydrate({router}) {
- window.addEventListener(router.event, () => {
- console.log(router.url);
- });
- }
-
-}
-
-export default Analytics;
-
-Anchor tags accept some convenient special attributes besides the regular href.
You can set the params attribute with an object as the value.
The path will remain the same as the current router path, but the params will be replaced by the new params you specify.
<a params={{page: 1}}> First Page </a>
-
-If you wish to just update some params and keep the others, you can use the javascript spread operator for that.
-<a params={{...params, page: 1}}> First Page </a>
-
-You can set the path attribute with a string starting with "/" and no query params.
The params will remain the same, but the path will be updated.
<a path="/category/suspense"> Suspense Books </a>
-
-Both attributes above can be used at the same time.
-<a path="/category/suspense" params={{...params, page: 1}}> Suspense Books </a>
-
-The first route to be matched will be rendered.
-The other elements with a route will not be rendered, however, elements on the same level without a route attribute will render normally.
The router will lookup for one route per dom depth level, this allows you to have nested routing behavior.
-import Nullstack from 'nullstack';
-import Home from './Home';
-
-class Application extends Nullstack {
-
- renderPage() {
- return (
- <section>
- <div route="/page/about"> About Page </div>
- <div route="/page/contact"> Contact Page </div>
- </section>
- )
- }
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <Page route="/page/:slug" />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-⚔ Learn about two-way bindings.
-Nullstack has built-in routes, it would make no sense otherwise since web applications are expected to have hyperlinks.
-Any tag can receive a route attribute, be it a component, inner component, or simple HTML tag.
import Nullstack from 'nullstack';
-import Page from './Page';
-
-class Application extends Nullstack {
-
- renderHome() {
- return (
- <section> Home </section>
- )
- }
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <Page route="/page" />
- <abbr route="/abbreviations"> Abbreviations </abbr>
- </main>
- )
- }
-
-}
-
-export default Application;
-
-Links on Nullstack are simple a tags with the href value starting with "/".
<a href="/page/about"> About Page </a>
-
---💡 On the client side the click event will push history without reloading the page.
-
--✨ You can still assign your own click event to the tag without losing the framework behavior.
-
The params key is an object proxy injected into every client instance.
Each query string param is mapped to this object.
-By default any key you request from this object will return a string.
-If the value is undefined it will return an empty string.
If the value is true or false it will return a boolean instead.
--🐱💻 Bellow an exemple that visits "/books?expanded=true&page=2":
-
import Nullstack from 'nullstack';
-
-class Books extends Nullstack {
-
- async initiate({params}) {
- if(params.expanded) {
- const page = parseInt(params.page) || 1;
- this.books = await this.getBooks({page});
- }
- }
-
-}
-
-export default Books;
-
-Assigning to a params key will cause a redirect to the route with updated params.
-When you assign to a param, the value will be converted to JSON before being set.
---💡 Redirects work in batches, so there is no performance loss in multiple assignments.
-
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- handleClick({params}) {
- params.filter = '';
- params.page = 1;
- }
-
-}
-
-export default Paginator;
-
-Assigning an empty string to a param will remove it from the url.
-Part of the route can be an expression started with ":" followed by a param name.
-This value will be matched against any string in the same directory position.
-The value of the string in the URL will be assigned to the context params and functions below this point in the hierarchy will have access to the new key.
---🐱💻 Bellow an example that visits "/category/suspense?page=2":
-
import Nullstack from 'nullstack';
-
-class Books extends Nullstack {
-
- async initiate({params}) {
- const page = parseInt(params.page) || 1;
- const category = params.slug;
- this.books = await this.getBooks({category, page});
- }
-
-}
-
-export default Books;
-
-import Nullstack from 'nullstack';
-import Books from './Books';
-
-class Application extends Nullstack {
-
- render() {
- <main>
- <Books route="/category/:slug">
- </main>
- }
-
-}
-
-export default Application;
-
-When a dynamic segment is changed, as for example moving from "/category/suspense" to "/category/comedy", the component will be terminated and a new instance will be created.
-Changing a query param will not re-instantiate the component.
-Children of the component will not be re-instantiated automatically, you can set the same route to the children or do it manually if you desire this behavior.
---💡 The behavior mentioned above solves many of the problems you have to normally deal with manually.
-
Wildcards are routes declared with "*" as the attribute value.
-These routes will match anything if nothing above it matches the requested URL.
-import Nullstack from 'nullstack';
-import Home from './Home';
-
-class Application extends Nullstack {
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <div route="*"> Wildcard </div>
- </main>
- )
- }
-
-}
-
-Wildcards can be prefixed with a segment.
---✨ this is especially useful for engines that can be mounted in your application.
-
import Nullstack from 'nullstack';
-import Home from './Home';
-import BlogEngine from './BlogEngine';
-
-class Application extends Nullstack {
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <BlogEngine route="/blog/*" />
- </main>
- )
- }
-
-}
-
-The router key is an object proxy injected into every client instance.
The router has two keys:
urlpathThe url key returns everything after the domain including the path and the query params as a string.
The path key returns only the path without query params.
--💡 Both keys above automatically remove the trailing slash for convenience.
-
Assigning to url or path will cause a redirect.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- prepare({router}) {
- if(router.path == '/') {
- router.path = '/dashboard';
- }
- }
-
-}
-
---💡 Under the hood
-atags withparamsuse therouter.
Updating router.url or router.path will raise a custom event.
import Nullstack from 'nullstack';
-
-class Analytics extends Nullstack {
-
- hydrate({router}) {
- window.addEventListener(router.event, () => {
- console.log(router.url);
- });
- }
-
-}
-
-export default Analytics;
-
-Anchor tags accept some convenient special attributes besides the regular href.
You can set the params attribute with an object as the value.
The path will remain the same as the current router path, but the params will be replaced by the new params you specify.
<a params={{page: 1}}> First Page </a>
-
-If you wish to just update some params and keep the others, you can use the javascript spread operator for that.
-<a params={{...params, page: 1}}> First Page </a>
-
-You can set the path attribute with a string starting with "/" and no query params.
The params will remain the same, but the path will be updated.
<a path="/category/suspense"> Suspense Books </a>
-
-Both attributes above can be used at the same time.
-<a path="/category/suspense" params={{...params, page: 1}}> Suspense Books </a>
-
-The first route to be matched will be rendered.
-The other elements with a route will not be rendered, however, elements on the same level without a route attribute will render normally.
The router will lookup for one route per dom depth level, this allows you to have nested routing behavior.
-import Nullstack from 'nullstack';
-import Home from './Home';
-
-class Application extends Nullstack {
-
- renderPage() {
- return (
- <section>
- <div route="/page/about"> About Page </div>
- <div route="/page/contact"> Contact Page </div>
- </section>
- )
- }
-
- render({count}) {
- return (
- <main>
- <Home route="/" />
- <Page route="/page/:slug" />
- </main>
- )
- }
-
-}
-
-export default Application;
-
-⚔ Learn about two-way bindings.
-Nullstack has built-in routes, it would make no sense otherwise since web applications are expected to have hyperlinks.
\nAny tag can receive a route attribute, be it a component, inner component, or simple HTML tag.
import Nullstack from 'nullstack';\nimport Page from './Page';\n\nclass Application extends Nullstack {\n\n renderHome() {\n return (\n <section> Home </section>\n )\n }\n \n render({count}) {\n return (\n <main>\n <Home route=\"/\" />\n <Page route=\"/page\" />\n <abbr route=\"/abbreviations\"> Abbreviations </abbr>\n </main>\n )\n }\n\n}\n\nexport default Application;\n\nLinks on Nullstack are simple a tags with the href value starting with "/".
<a href=\"/page/about\"> About Page </a>\n\n\n\n💡 On the client side the click event will push history without reloading the page.
\n
\n\n✨ You can still assign your own click event to the tag without losing the framework behavior.
\n
The params key is an object proxy injected into every client instance.
Each query string param is mapped to this object.
\nBy default any key you request from this object will return a string.
\nIf the value is undefined it will return an empty string.
If the value is true or false it will return a boolean instead.
\n\n🐱💻 Bellow an exemple that visits "/books?expanded=true&page=2":
\n
import Nullstack from 'nullstack';\n\nclass Books extends Nullstack {\n\n async initiate({params}) {\n if(params.expanded) {\n const page = parseInt(params.page) || 1;\n this.books = await this.getBooks({page});\n }\n }\n\n}\n\nexport default Books;\n\nAssigning to a params key will cause a redirect to the route with updated params.
\nWhen you assign to a param, the value will be converted to JSON before being set.
\n\n\n💡 Redirects work in batches, so there is no performance loss in multiple assignments.
\n
import Nullstack from 'nullstack';\n\nclass Paginator extends Nullstack {\n\n handleClick({params}) {\n params.filter = '';\n params.page = 1;\n }\n\n}\n\nexport default Paginator;\n\nAssigning an empty string to a param will remove it from the url.
\nPart of the route can be an expression started with ":" followed by a param name.
\nThis value will be matched against any string in the same directory position.
\nThe value of the string in the URL will be assigned to the context params and functions below this point in the hierarchy will have access to the new key.
\n\n\n🐱💻 Bellow an example that visits "/category/suspense?page=2":
\n
import Nullstack from 'nullstack';\n\nclass Books extends Nullstack {\n\n async initiate({params}) {\n const page = parseInt(params.page) || 1;\n const category = params.slug;\n this.books = await this.getBooks({category, page});\n }\n\n}\n\nexport default Books;\n\nimport Nullstack from 'nullstack';\nimport Books from './Books';\n\nclass Application extends Nullstack {\n\n render() {\n <main>\n <Books route=\"/category/:slug\">\n </main>\n }\n\n}\n\nexport default Application;\n\nWhen a dynamic segment is changed, as for example moving from "/category/suspense" to "/category/comedy", the component will be terminated and a new instance will be created.
\nChanging a query param will not re-instantiate the component.
\nChildren of the component will not be re-instantiated automatically, you can set the same route to the children or do it manually if you desire this behavior.
\n\n\n💡 The behavior mentioned above solves many of the problems you have to normally deal with manually.
\n
Wildcards are routes declared with "*" as the attribute value.
\nThese routes will match anything if nothing above it matches the requested URL.
\nimport Nullstack from 'nullstack';\nimport Home from './Home';\n\nclass Application extends Nullstack {\n\n render({count}) {\n return (\n <main>\n <Home route=\"/\" />\n <div route=\"*\"> Wildcard </div>\n </main>\n )\n }\n\n}\n\nWildcards can be prefixed with a segment.
\n\n\n✨ this is especially useful for engines that can be mounted in your application.
\n
import Nullstack from 'nullstack';\nimport Home from './Home';\nimport BlogEngine from './BlogEngine';\n\nclass Application extends Nullstack {\n\n render({count}) {\n return (\n <main>\n <Home route=\"/\" />\n <BlogEngine route=\"/blog/*\" />\n </main>\n )\n }\n\n}\n\nThe router key is an object proxy injected into every client instance.
The router has two keys:
urlpathThe url key returns everything after the domain including the path and the query params as a string.
The path key returns only the path without query params.
\n\n💡 Both keys above automatically remove the trailing slash for convenience.
\n
Assigning to url or path will cause a redirect.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n prepare({router}) {\n if(router.path == '/') {\n router.path = '/dashboard';\n }\n }\n\n}\n\n\n\n💡 Under the hood
\natags withparamsuse therouter.
Updating router.url or router.path will raise a custom event.
import Nullstack from 'nullstack';\n\nclass Analytics extends Nullstack {\n\n hydrate({router}) {\n window.addEventListener(router.event, () => {\n console.log(router.url);\n });\n }\n\n}\n\nexport default Analytics;\n\nAnchor tags accept some convenient special attributes besides the regular href.
You can set the params attribute with an object as the value.
The path will remain the same as the current router path, but the params will be replaced by the new params you specify.
<a params={{page: 1}}> First Page </a>\n\nIf you wish to just update some params and keep the others, you can use the javascript spread operator for that.
\n<a params={{...params, page: 1}}> First Page </a>\n\nYou can set the path attribute with a string starting with "/" and no query params.
The params will remain the same, but the path will be updated.
<a path=\"/category/suspense\"> Suspense Books </a>\n\nBoth attributes above can be used at the same time.
\n<a path=\"/category/suspense\" params={{...params, page: 1}}> Suspense Books </a>\n\nThe first route to be matched will be rendered.
\nThe other elements with a route will not be rendered, however, elements on the same level without a route attribute will render normally.
The router will lookup for one route per dom depth level, this allows you to have nested routing behavior.
\nimport Nullstack from 'nullstack';\nimport Home from './Home';\n\nclass Application extends Nullstack {\n\n renderPage() {\n return (\n <section>\n <div route=\"/page/about\"> About Page </div>\n <div route=\"/page/contact\"> Contact Page </div>\n </section>\n )\n }\n \n render({count}) {\n return (\n <main>\n <Home route=\"/\" />\n <Page route=\"/page/:slug\" />\n </main>\n )\n }\n\n}\n\nexport default Application;\n\n⚔ Learn about two-way bindings.
\n","description":"Nullstack has built-in routes, it would make no sense otherwise since web applications are expected to have hyperlinks."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Routes and Params - Nullstack","description":"Nullstack has built-in routes, it would make no sense otherwise since web applications are expected to have hyperlinks."}} \ No newline at end of file diff --git a/docs/server-functions.html b/docs/server-functions.html deleted file mode 100644 index 0e92987a..00000000 --- a/docs/server-functions.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - - -Server functions are specialized microservices that at transpile time are converted into API entry points.
-To flag a function as a server function, you must declare it as static async.
Being a static function means it has no access to the instance scope.
-However, instead of calling the static version from the class, you must invoke it as an instance function.
-Server functions can be called anytime in your code and are not limited to prerender steps.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async increment(context) {
- context.count++;
- }
-
- async handleClick() {
- await this.increment();
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Learn more about the server context.
-
When you call a server function from the client, the arguments will be serialized as JSON.
-The arguments will be posted against the automatically generated API and merged with the server context when it reaches the server.
-The return value of the server function will be serialized back to the client and can be seamlessly used as if it were a local function.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async increment(context) {
- context.count++;
- return context.count;
- }
-
- async handleClick() {
- this.count = await this.increment();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Server functions will be used as local functions, simply aliasing the instance call to the class and merging the arguments with the server context.
-Dates are serialized as UTC in JSON and deserialized back to Date objects.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- async initiate() {
- const date = new Date();
- const verified = this.verifyDay({date});
- }
-
- static async verifyDay({date}) {
- return date.getDay() === new Date().getDay();
- }
-
- // ...
-
-}
-
-export default Component;
-
-fetch is available in both server and client functions for the sake of isomorphy.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async initiate() {
- const url = 'https://api.github.com/repos/nullstack/nullstack/issues';
- const response = await fetch(url);
- this.issues = await response.json();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Imported dependencies that are only used inside server functions will be excluded from the client bundle.
-This is useful for both accessing node.js exclusive modules and reducing the client bundle size by preprocessing data like markdown without having to expose the dependency to the end-user.
-import Nullstack from 'nullstack';
-import {readFileSync} from 'fs';
-import {Remarkable} from 'remarkable';
-
-class Application extends Nullstack {
-
- static async getTasks() {
- const readme = readFileSync('README.md', 'utf-8');
- return new Remarkable().render(readme);
- }
-
- // ...
-
-}
-
-export default Application;
-
-Keep in mind that every server function is similar to an Express route in API and must be coded without depending on view logic for security.
---🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
-
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async getCount({request, count}) {
- if(!request.session.user) return 0;
- return count;
- }
-
- // ...
-
-}
-
-export default Component;
-
---💡 Server functions are not exposed to the client.
-
--✨ Learn more about the NJS file extension.
-
Server function names cannot collide with instance method names from the current class or its parent classes.
-The following words cannot be used in server functions:
-prepareinitiatehydrateupdateterminateServer functions named start will not generate an API endpoint and can only be called by other server functions.
Automatically generated API endpoints are not meant to be used by 3rd-party apps.
-The URL and implementation may change between versions of Nullstack.
---✨ If you want to build an API, learn more about how to create an API with Nullstack.
-
⚔ Learn about the context.
-Server functions are specialized microservices that at transpile time are converted into API entry points.
-To flag a function as a server function, you must declare it as static async.
Being a static function means it has no access to the instance scope.
-However, instead of calling the static version from the class, you must invoke it as an instance function.
-Server functions can be called anytime in your code and are not limited to prerender steps.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async increment(context) {
- context.count++;
- }
-
- async handleClick() {
- await this.increment();
- }
-
- // ...
-
-}
-
-export default Component;
-
---✨ Learn more about the server context.
-
When you call a server function from the client, the arguments will be serialized as JSON.
-The arguments will be posted against the automatically generated API and merged with the server context when it reaches the server.
-The return value of the server function will be serialized back to the client and can be seamlessly used as if it were a local function.
-import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async increment(context) {
- context.count++;
- return context.count;
- }
-
- async handleClick() {
- this.count = await this.increment();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Server functions will be used as local functions, simply aliasing the instance call to the class and merging the arguments with the server context.
-Dates are serialized as UTC in JSON and deserialized back to Date objects.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- async initiate() {
- const date = new Date();
- const verified = this.verifyDay({date});
- }
-
- static async verifyDay({date}) {
- return date.getDay() === new Date().getDay();
- }
-
- // ...
-
-}
-
-export default Component;
-
-fetch is available in both server and client functions for the sake of isomorphy.
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- // ...
-
- async initiate() {
- const url = 'https://api.github.com/repos/nullstack/nullstack/issues';
- const response = await fetch(url);
- this.issues = await response.json();
- }
-
- // ...
-
-}
-
-export default Component;
-
-Imported dependencies that are only used inside server functions will be excluded from the client bundle.
-This is useful for both accessing node.js exclusive modules and reducing the client bundle size by preprocessing data like markdown without having to expose the dependency to the end-user.
-import Nullstack from 'nullstack';
-import {readFileSync} from 'fs';
-import {Remarkable} from 'remarkable';
-
-class Application extends Nullstack {
-
- static async getTasks() {
- const readme = readFileSync('README.md', 'utf-8');
- return new Remarkable().render(readme);
- }
-
- // ...
-
-}
-
-export default Application;
-
-Keep in mind that every server function is similar to an Express route in API and must be coded without depending on view logic for security.
---🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
-
import Nullstack from 'nullstack';
-
-class Component extends Nullstack {
-
- static async getCount({request, count}) {
- if(!request.session.user) return 0;
- return count;
- }
-
- // ...
-
-}
-
-export default Component;
-
---💡 Server functions are not exposed to the client.
-
--✨ Learn more about the NJS file extension.
-
Server function names cannot collide with instance method names from the current class or its parent classes.
-The following words cannot be used in server functions:
-prepareinitiatehydrateupdateterminateServer functions named start will not generate an API endpoint and can only be called by other server functions.
Automatically generated API endpoints are not meant to be used by 3rd-party apps.
-The URL and implementation may change between versions of Nullstack.
---✨ If you want to build an API, learn more about how to create an API with Nullstack.
-
⚔ Learn about the context.
-Server functions are specialized microservices that at transpile time are converted into API entry points.
\nTo flag a function as a server function, you must declare it as static async.
Being a static function means it has no access to the instance scope.
\nHowever, instead of calling the static version from the class, you must invoke it as an instance function.
\nServer functions can be called anytime in your code and are not limited to prerender steps.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n static async increment(context) {\n context.count++;\n }\n\n async handleClick() {\n await this.increment();\n }\n\n // ...\n\n}\n\nexport default Component;\n\n\n\n✨ Learn more about the server context.
\n
When you call a server function from the client, the arguments will be serialized as JSON.
\nThe arguments will be posted against the automatically generated API and merged with the server context when it reaches the server.
\nThe return value of the server function will be serialized back to the client and can be seamlessly used as if it were a local function.
\nimport Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n static async increment(context) {\n context.count++;\n return context.count;\n }\n\n async handleClick() {\n this.count = await this.increment();\n }\n\n // ...\n\n}\n\nexport default Component;\n\nServer functions will be used as local functions, simply aliasing the instance call to the class and merging the arguments with the server context.
\nDates are serialized as UTC in JSON and deserialized back to Date objects.
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n async initiate() {\n const date = new Date();\n const verified = this.verifyDay({date});\n }\n\n static async verifyDay({date}) {\n return date.getDay() === new Date().getDay();\n }\n\n // ...\n\n}\n\nexport default Component;\n\nfetch is available in both server and client functions for the sake of isomorphy.
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n // ...\n\n async initiate() {\n const url = 'https://api.github.com/repos/nullstack/nullstack/issues';\n const response = await fetch(url);\n this.issues = await response.json();\n }\n\n // ...\n\n}\n\nexport default Component;\n\nImported dependencies that are only used inside server functions will be excluded from the client bundle.
\nThis is useful for both accessing node.js exclusive modules and reducing the client bundle size by preprocessing data like markdown without having to expose the dependency to the end-user.
\nimport Nullstack from 'nullstack';\nimport {readFileSync} from 'fs';\nimport {Remarkable} from 'remarkable';\n\nclass Application extends Nullstack {\n\n static async getTasks() {\n const readme = readFileSync('README.md', 'utf-8');\n return new Remarkable().render(readme);\n }\n\n // ...\n\n}\n\nexport default Application;\n\nKeep in mind that every server function is similar to an Express route in API and must be coded without depending on view logic for security.
\n\n\n🔒 Server functions with the name starting with "start" (and optionally followed by an uppercase letter) do not generate an API endpoint to avoid malicious context flooding.
\n
import Nullstack from 'nullstack';\n\nclass Component extends Nullstack {\n\n static async getCount({request, count}) {\n if(!request.session.user) return 0;\n return count;\n }\n\n // ...\n\n}\n\nexport default Component;\n\n\n\n💡 Server functions are not exposed to the client.
\n
\n\n✨ Learn more about the NJS file extension.
\n
Server function names cannot collide with instance method names from the current class or its parent classes.
\nThe following words cannot be used in server functions:
\nprepareinitiatehydrateupdateterminateServer functions named start will not generate an API endpoint and can only be called by other server functions.
Automatically generated API endpoints are not meant to be used by 3rd-party apps.
\nThe URL and implementation may change between versions of Nullstack.
\n\n\n✨ If you want to build an API, learn more about how to create an API with Nullstack.
\n
⚔ Learn about the context.
\n","description":"Server functions are specialized microservices that at transpile time are converted into API entry points"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Server Functions - Nullstack","description":"Server functions are specialized microservices that at transpile time are converted into API entry points"}} \ No newline at end of file diff --git a/docs/server-request-and-response.html b/docs/server-request-and-response.html deleted file mode 100644 index 63b981ec..00000000 --- a/docs/server-request-and-response.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - -The server key is a proxy around the Express instance that runs Nullstack under the hood.
-The server object is present only in the server context.
-The following functions are tunneled back to the Express server:
-getpostputpatchdeleteoptionsheaduse--✨ If you wanna know how to make an API with Nullstack, this is the way.
-
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({server}) {
- server.get('/api/books', (request, response) => {
- response.json({books: []});
- });
- }
-
- // ...
-
-}
-
-export default Application;
-
-Other available keys are:
-integerstringobjectimport Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({server}) {
- server.port = 3000;
- server.maximumPayloadSize = '5mb';
- server.cors = {
- origin: 'http://localhost:6969',
- optionsSuccessStatus: 200
- }
- }
-
- // ...
-
-}
-
-export default Application;
-
-The cors object will be passed as the argument to express cors plugin.
Every server function context is merged with the original request and response objects from Express.
If you raise a response manually it will override the framework's server-side rendering response.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async getBooks({request, response}) {
- if(!request.session.user) {
- response.status(401).json({unauthorized: true});
- }
- }
-
- // ...
-
-}
-
-export default Application;
-
-⚔ Learn about styles.
-The server key is a proxy around the Express instance that runs Nullstack under the hood.
-The server object is present only in the server context.
-The following functions are tunneled back to the Express server:
-getpostputpatchdeleteoptionsheaduse--✨ If you wanna know how to make an API with Nullstack, this is the way.
-
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({server}) {
- server.get('/api/books', (request, response) => {
- response.json({books: []});
- });
- }
-
- // ...
-
-}
-
-export default Application;
-
-Other available keys are:
-integerstringobjectimport Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async start({server}) {
- server.port = 3000;
- server.maximumPayloadSize = '5mb';
- server.cors = {
- origin: 'http://localhost:6969',
- optionsSuccessStatus: 200
- }
- }
-
- // ...
-
-}
-
-export default Application;
-
-The cors object will be passed as the argument to express cors plugin.
Every server function context is merged with the original request and response objects from Express.
If you raise a response manually it will override the framework's server-side rendering response.
import Nullstack from 'nullstack';
-
-class Application extends Nullstack {
-
- static async getBooks({request, response}) {
- if(!request.session.user) {
- response.status(401).json({unauthorized: true});
- }
- }
-
- // ...
-
-}
-
-export default Application;
-
-⚔ Learn about styles.
-The server key is a proxy around the Express instance that runs Nullstack under the hood.
\nThe server object is present only in the server context.
\nThe following functions are tunneled back to the Express server:
\ngetpostputpatchdeleteoptionsheaduse\n\n✨ If you wanna know how to make an API with Nullstack, this is the way.
\n
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({server}) {\n server.get('/api/books', (request, response) => {\n response.json({books: []});\n });\n }\n\n // ...\n\n}\n\nexport default Application;\n\nOther available keys are:
\nintegerstringobjectimport Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async start({server}) {\n server.port = 3000;\n server.maximumPayloadSize = '5mb';\n server.cors = {\n origin: 'http://localhost:6969',\n optionsSuccessStatus: 200\n }\n }\n\n // ...\n\n}\n\nexport default Application;\n\nThe cors object will be passed as the argument to express cors plugin.
Every server function context is merged with the original request and response objects from Express.
If you raise a response manually it will override the framework's server-side rendering response.
import Nullstack from 'nullstack';\n\nclass Application extends Nullstack {\n\n static async getBooks({request, response}) {\n if(!request.session.user) {\n response.status(401).json({unauthorized: true});\n }\n }\n\n // ...\n\n}\n\nexport default Application;\n\n⚔ Learn about styles.
\n","description":"The server key is a proxy around the express instance that runs Nullstack under the hood"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Server request and response - Nullstack","description":"The server key is a proxy around the express instance that runs Nullstack under the hood"}} \ No newline at end of file diff --git a/docs/server-side-rendering.html b/docs/server-side-rendering.html deleted file mode 100644 index 6d6cfe5c..00000000 --- a/docs/server-side-rendering.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from.
-Server-side rendering is good for SEO since it gives as fast as possible crawlable markup for search engines.
-Nullstack starts the application for the user by first serving HTML of only the requested page with no overhead.
-Before serving the HTML, Nullstack will wait for prepare and initiate of all components of that route to be resolved.
While server-side rendering all server functions run locally without the need to fetch an API, making the process even faster.
-After the document is already painted in the browser, Nullstack loads the javascript client bundle and starts the hydration process.
-No further requests to the server are made to recover the application state during hydration.
-The page head will generate the necessary meta tags for SEO based on the contents of the project and page context keys.
⚔ Learn about static site generation.
-Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from.
-Server-side rendering is good for SEO since it gives as fast as possible crawlable markup for search engines.
-Nullstack starts the application for the user by first serving HTML of only the requested page with no overhead.
-Before serving the HTML, Nullstack will wait for prepare and initiate of all components of that route to be resolved.
While server-side rendering all server functions run locally without the need to fetch an API, making the process even faster.
-After the document is already painted in the browser, Nullstack loads the javascript client bundle and starts the hydration process.
-No further requests to the server are made to recover the application state during hydration.
-The page head will generate the necessary meta tags for SEO based on the contents of the project and page context keys.
⚔ Learn about static site generation.
-Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from.
\nServer-side rendering is good for SEO since it gives as fast as possible crawlable markup for search engines.
\nNullstack starts the application for the user by first serving HTML of only the requested page with no overhead.
\nBefore serving the HTML, Nullstack will wait for prepare and initiate of all components of that route to be resolved.
While server-side rendering all server functions run locally without the need to fetch an API, making the process even faster.
\nAfter the document is already painted in the browser, Nullstack loads the javascript client bundle and starts the hydration process.
\nNo further requests to the server are made to recover the application state during hydration.
\nThe page head will generate the necessary meta tags for SEO based on the contents of the project and page context keys.
⚔ Learn about static site generation.
\n","description":"Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Server-Side Rendering - Nullstack","description":"Nullstack optimizes SEO and response times out of the box by generating HTML for the route that you enter the application from"}} \ No newline at end of file diff --git a/docs/service-worker-9cdb5778f42a90a83e1427c9316c97d3.js b/docs/service-worker-9cdb5778f42a90a83e1427c9316c97d3.js deleted file mode 100644 index f2d2e47f..00000000 --- a/docs/service-worker-9cdb5778f42a90a83e1427c9316c97d3.js +++ /dev/null @@ -1,234 +0,0 @@ -self.context = { - "environment": { - "client": false, - "server": true, - "development": false, - "production": true, - "static": true, - "key": "9cdb5778f42a90a83e1427c9316c97d3" - }, - "project": { - "type": "website", - "display": "standalone", - "orientation": "portrait", - "scope": "/", - "root": "/", - "favicon": "/favicon-96x96.png", - "icons": { - "72": "/icon-72x72.png", - "96": "/icon-96x96.png", - "128": "/icon-128x128.png", - "144": "/icon-144x144.png", - "152": "/icon-152x152.png", - "180": "/icon-180x180.png", - "192": "/icon-192x192.png", - "384": "/icon-384x384.png", - "512": "/icon-512x512.png" - }, - "disallow": [], - "sitemap": true, - "cdn": "", - "protocol": "https", - "name": "Nullstack", - "domain": "nullstack.app", - "color": "#d22365", - "backgroundColor": "#2d3748" - }, - "settings": {}, - "worker": { - "enabled": true, - "fetching": false, - "preload": [ - "/404", - "/about", - "/application-startup", - "/context-data", - "/context-environment", - "/context-page", - "/context-project", - "/context-secrets", - "/context-settings", - "/context", - "/full-stack-lifecycle", - "/getting-started", - "/how-to-deploy-a-nullstack-application", - "/how-to-use-facebook-pixel-with-nullstack", - "/how-to-use-google-analytics-with-nullstack", - "/how-to-use-mongodb-with-nullstack", - "/instance-self", - "/njs-file-extension", - "/renderable-components", - "/routes-and-params", - "/server-functions", - "/server-request-and-response", - "/server-side-rendering", - "/service-worker", - "/stateful-components", - "/static-site-generation", - "/styles", - "/two-way-bindings", - "/documentation", - "/components", - "/about", - "/contributors", - "/roboto-v20-latin-300.woff2", - "/roboto-v20-latin-500.woff2", - "/crete-round-v9-latin-regular.woff2", - "/nullachan.png" - ], - "headers": {}, - "queues": {} - } -}; - -async function load(event) { - const response = await event.preloadResponse; - if (response) return response; - return await fetch(event.request); -} - -function toAPI(url) { - let [path, query] = url.split('?'); - if(path.indexOf('.') === -1) { - path += '/index.json'; - } - return query ? `${path}?${query}` : path; -} - -async function extractData(response) { - const html = await response.clone().text(); - const instancesLookup = 'window.instances = '; - const instances = html.split("\n").find((line) => line.indexOf(instancesLookup) > -1).split(instancesLookup)[1].slice(0, -1); - const pageLookup = 'window.page = '; - const page = html.split("\n").find((line) => line.indexOf(pageLookup) > -1).split(pageLookup)[1].slice(0, -1); - const json = `{"instances": ${instances}, "page": ${page}}`; - return new Response(json, { - headers: {'Content-Type': 'application/json'} - }); -} - -async function injectData(templateResponse, cachedDataResponse) { - const data = await cachedDataResponse.json(); - const input = await templateResponse.text(); - const output = input.split(`\n`).map((line) => { - if(line.indexOf('objectIt gives you granular control of your PWA behavior.
-worker keys will be used to generate the service worker file and should be set during the application startup.
worker keys are frozen after the application startup.
The following keys are available in the object during the startup:
-booleanstring array (relative paths)objectThe enabled key defines if the service worker will be automatically registered by Nullstack.
By default enabled is set to true on production mode and false on development mode.
preload is an array of paths that will be cached when the service worker is installed.
The assets required to start the application will be preloaded automatically, and you should configure only the extra pages you want to have available offline.
-import Nullstack from 'nullstack';
-import path from 'path';
-import {readdirSync} from 'fs';
-
-class Application extends Nullstack {
-
- static async start({worker}) {
- const articles = readdirSync(path.join(__dirname, '..', 'articles'));
- worker.preload = [
- ...articles.map((article) => '/' + article.replace('.md', '')),
- '/nullstack.svg',
- '/documentation',
- '/components'
- ]
- }
-
- // ...
-
-}
-
-export default Application;
-
---💡 the example above is extracted from this repository and allows the documentation to be fully accessible offline.
-
The following keys are available as readonly in the client context:
-booleanstring array (relative paths)booleanbooleanbooleanBeforeInstallPromptEventServiceWorkerRegistrationobjectThe following keys are available as readwrite in the client context:
-objectThe responsive key determines if the application has all the responses it needs to render the current page.
Nullstack will try to keep your application responsive as long as possible and set the key to false only when there are no ways of retrieving any response from the network or offline according to the fetch strategy for the environment.
The online key will listen for network events and rerender the application when navigator.onLine value changes.
When the application is back online Nullstack will try to make the application responsive again and rerender if necessary.
-import Nullstack from 'nullstack';
-// ...
-
-class Application extends Nullstack {
-
- // ...
-
- render({worker}) {
- if(!worker.responsive) {
- return <OfflineWarning />
- }
- return (
- <main>
- <Home route="/" />
- </main>
- )
- }
-
-}
-
-You can access the current service worker registration and installation from the worker key to control the flow of your PWA.
The registration key refers to the service worker registration and will be only available once the registration process is complete.
The installation key refers to the deferred installation prompt event and will only be available if the beforeinstallprompt event is triggered.
import Nullstack from 'nullstack';
-
-class PWAInstaller extends Nullstack {
-
- installed = false;
- hidden = false;
-
- async prompt({worker}) {
- try {
- worker.installation.prompt();
- const {outcome} = await worker.installation.userChoice;
- if (outcome === 'accepted') {
- console.log('User accepted the A2HS prompt');
- } else {
- console.log('User dismissed the A2HS prompt');
- }
- } finally {
- this.hidden = true;
- }
- }
-
- render({worker, project}) {
- if(this.hidden) return false;
- if(!worker.installation) return false;
- return (
- <div>
- <img src={project.favicon} />
- <p> Do you want to add {project.name} to your home screen?</p>
- <button onclick={this.prompt}> Install </button>
- <button onclick={{hidden: true}}> Not Now </button>
- </div>
- )
- }
-
-}
-
-export default PWAInstaller;
-
-When a server function is called fetching will be set to true until the response is resolved.
When a server function is called a key with the name of the server function invoked will be set to true in the loading key until the response is resolved.
Any key you invoke on the loading object will always return a boolean instead of undefined for consistency.
When the server is emulating the client context for server-side rendering, every key of the loading object will always return false, saving multiple render cycles in performance.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- static async save() {
- // ...
- }
-
- async submit() {
- await this.save();
- }
-
- render({worker}) {
- return (
- <form onsubmit={this.save}>
- {worker.fetching &&
- <span> loading... </span>
- }
- <button disabled={worker.loading.save}>
- Save
- </button>
- </form>
- )
- }
-
-}
-
-export default Page;
-
-You can use the headers key to configure the headers that the worker will use when fetching a server function.
--🔥 Headers will be ignored when a server function is called during the server-side rendering process.
-
import Nullstack from 'nullstack';
-
-class LoginPage extends Nullstack {
-
- // ...
-
- async submit({worker}) {
- // ...
- this.headers['Authorization'] = `Bearer ${token}`;
- // ...
- }
-
- static async authorize({request}) {
- const authorization = request.headers['Authorization'];
- // ...
- }
-
- // ...
-
-}
-
-
-export default LoginPage;
-
---✨ Learn more about the server request and response
-
worker.responsive and worker.online are set to false;worker.responsive and worker.online are set to false;Nullstack will install automatically your service worker if enabled is set to true with the following events:
installactivatefetchYou can override any of those events by creating a service-worker.js in the public folder;
-If any of the keywords above are found Nullstack will inject your function in the service worker code instead of the default.
-For convenience a context key is injected in the service worker self with the following keys:
workerprojectenvironmentfunction activate(event) {
- event.waitUntil(async function() {
- const cacheNames = await caches.keys();
- const cachesToDelete = cacheNames.filter(cacheName => cacheName !== self.context.environment.key);
- await Promise.all(cachesToDelete.map((cacheName) => caches.delete(cacheName)));
- if (self.registration.navigationPreload) {
- await self.registration.navigationPreload.enable();
- }
- self.clients.claim();
- }());
-}
-
-self.addEventListener('activate', activate);
-
---💡 The example above is extracted from the generated service worker and uses
-self.context.environment.key
objectIt gives you granular control of your PWA behavior.
-worker keys will be used to generate the service worker file and should be set during the application startup.
worker keys are frozen after the application startup.
The following keys are available in the object during the startup:
-booleanstring array (relative paths)objectThe enabled key defines if the service worker will be automatically registered by Nullstack.
By default enabled is set to true on production mode and false on development mode.
preload is an array of paths that will be cached when the service worker is installed.
The assets required to start the application will be preloaded automatically, and you should configure only the extra pages you want to have available offline.
-import Nullstack from 'nullstack';
-import path from 'path';
-import {readdirSync} from 'fs';
-
-class Application extends Nullstack {
-
- static async start({worker}) {
- const articles = readdirSync(path.join(__dirname, '..', 'articles'));
- worker.preload = [
- ...articles.map((article) => '/' + article.replace('.md', '')),
- '/nullstack.svg',
- '/documentation',
- '/components'
- ]
- }
-
- // ...
-
-}
-
-export default Application;
-
---💡 the example above is extracted from this repository and allows the documentation to be fully accessible offline.
-
The following keys are available as readonly in the client context:
-booleanstring array (relative paths)booleanbooleanbooleanBeforeInstallPromptEventServiceWorkerRegistrationobjectThe following keys are available as readwrite in the client context:
-objectThe responsive key determines if the application has all the responses it needs to render the current page.
Nullstack will try to keep your application responsive as long as possible and set the key to false only when there are no ways of retrieving any response from the network or offline according to the fetch strategy for the environment.
The online key will listen for network events and rerender the application when navigator.onLine value changes.
When the application is back online Nullstack will try to make the application responsive again and rerender if necessary.
-import Nullstack from 'nullstack';
-// ...
-
-class Application extends Nullstack {
-
- // ...
-
- render({worker}) {
- if(!worker.responsive) {
- return <OfflineWarning />
- }
- return (
- <main>
- <Home route="/" />
- </main>
- )
- }
-
-}
-
-You can access the current service worker registration and installation from the worker key to control the flow of your PWA.
The registration key refers to the service worker registration and will be only available once the registration process is complete.
The installation key refers to the deferred installation prompt event and will only be available if the beforeinstallprompt event is triggered.
import Nullstack from 'nullstack';
-
-class PWAInstaller extends Nullstack {
-
- installed = false;
- hidden = false;
-
- async prompt({worker}) {
- try {
- worker.installation.prompt();
- const {outcome} = await worker.installation.userChoice;
- if (outcome === 'accepted') {
- console.log('User accepted the A2HS prompt');
- } else {
- console.log('User dismissed the A2HS prompt');
- }
- } finally {
- this.hidden = true;
- }
- }
-
- render({worker, project}) {
- if(this.hidden) return false;
- if(!worker.installation) return false;
- return (
- <div>
- <img src={project.favicon} />
- <p> Do you want to add {project.name} to your home screen?</p>
- <button onclick={this.prompt}> Install </button>
- <button onclick={{hidden: true}}> Not Now </button>
- </div>
- )
- }
-
-}
-
-export default PWAInstaller;
-
-When a server function is called fetching will be set to true until the response is resolved.
When a server function is called a key with the name of the server function invoked will be set to true in the loading key until the response is resolved.
Any key you invoke on the loading object will always return a boolean instead of undefined for consistency.
When the server is emulating the client context for server-side rendering, every key of the loading object will always return false, saving multiple render cycles in performance.
import Nullstack from 'nullstack';
-
-class Page extends Nullstack {
-
- static async save() {
- // ...
- }
-
- async submit() {
- await this.save();
- }
-
- render({worker}) {
- return (
- <form onsubmit={this.save}>
- {worker.fetching &&
- <span> loading... </span>
- }
- <button disabled={worker.loading.save}>
- Save
- </button>
- </form>
- )
- }
-
-}
-
-export default Page;
-
-You can use the headers key to configure the headers that the worker will use when fetching a server function.
--🔥 Headers will be ignored when a server function is called during the server-side rendering process.
-
import Nullstack from 'nullstack';
-
-class LoginPage extends Nullstack {
-
- // ...
-
- async submit({worker}) {
- // ...
- this.headers['Authorization'] = `Bearer ${token}`;
- // ...
- }
-
- static async authorize({request}) {
- const authorization = request.headers['Authorization'];
- // ...
- }
-
- // ...
-
-}
-
-
-export default LoginPage;
-
---✨ Learn more about the server request and response
-
worker.responsive and worker.online are set to false;worker.responsive and worker.online are set to false;Nullstack will install automatically your service worker if enabled is set to true with the following events:
installactivatefetchYou can override any of those events by creating a service-worker.js in the public folder;
-If any of the keywords above are found Nullstack will inject your function in the service worker code instead of the default.
-For convenience a context key is injected in the service worker self with the following keys:
workerprojectenvironmentfunction activate(event) {
- event.waitUntil(async function() {
- const cacheNames = await caches.keys();
- const cachesToDelete = cacheNames.filter(cacheName => cacheName !== self.context.environment.key);
- await Promise.all(cachesToDelete.map((cacheName) => caches.delete(cacheName)));
- if (self.registration.navigationPreload) {
- await self.registration.navigationPreload.enable();
- }
- self.clients.claim();
- }());
-}
-
-self.addEventListener('activate', activate);
-
---💡 The example above is extracted from the generated service worker and uses
-self.context.environment.key
objectIt gives you granular control of your PWA behavior.
\nworker keys will be used to generate the service worker file and should be set during the application startup.
worker keys are frozen after the application startup.
The following keys are available in the object during the startup:
\nbooleanstring array (relative paths)objectThe enabled key defines if the service worker will be automatically registered by Nullstack.
By default enabled is set to true on production mode and false on development mode.
preload is an array of paths that will be cached when the service worker is installed.
The assets required to start the application will be preloaded automatically, and you should configure only the extra pages you want to have available offline.
\nimport Nullstack from 'nullstack';\nimport path from 'path';\nimport {readdirSync} from 'fs';\n\nclass Application extends Nullstack {\n\n static async start({worker}) {\n const articles = readdirSync(path.join(__dirname, '..', 'articles'));\n worker.preload = [\n ...articles.map((article) => '/' + article.replace('.md', '')),\n '/nullstack.svg',\n '/documentation',\n '/components'\n ]\n }\n \n // ...\n\n}\n\nexport default Application;\n\n\n\n💡 the example above is extracted from this repository and allows the documentation to be fully accessible offline.
\n
The following keys are available as readonly in the client context:
\nbooleanstring array (relative paths)booleanbooleanbooleanBeforeInstallPromptEventServiceWorkerRegistrationobjectThe following keys are available as readwrite in the client context:
\nobjectThe responsive key determines if the application has all the responses it needs to render the current page.
Nullstack will try to keep your application responsive as long as possible and set the key to false only when there are no ways of retrieving any response from the network or offline according to the fetch strategy for the environment.
The online key will listen for network events and rerender the application when navigator.onLine value changes.
When the application is back online Nullstack will try to make the application responsive again and rerender if necessary.
\nimport Nullstack from 'nullstack';\n// ...\n\nclass Application extends Nullstack {\n \n // ...\n\n render({worker}) {\n if(!worker.responsive) {\n return <OfflineWarning />\n }\n return (\n <main>\n <Home route=\"/\" />\n </main>\n )\n }\n\n}\n\nYou can access the current service worker registration and installation from the worker key to control the flow of your PWA.
The registration key refers to the service worker registration and will be only available once the registration process is complete.
The installation key refers to the deferred installation prompt event and will only be available if the beforeinstallprompt event is triggered.
import Nullstack from 'nullstack';\n\nclass PWAInstaller extends Nullstack {\n\n installed = false;\n hidden = false;\n\n async prompt({worker}) {\n try {\n worker.installation.prompt();\n const {outcome} = await worker.installation.userChoice;\n if (outcome === 'accepted') {\n console.log('User accepted the A2HS prompt');\n } else {\n console.log('User dismissed the A2HS prompt');\n }\n } finally {\n this.hidden = true;\n }\n }\n \n render({worker, project}) {\n if(this.hidden) return false;\n if(!worker.installation) return false;\n return (\n <div>\n <img src={project.favicon} />\n <p> Do you want to add {project.name} to your home screen?</p>\n <button onclick={this.prompt}> Install </button>\n <button onclick={{hidden: true}}> Not Now </button>\n </div>\n )\n }\n\n}\n\nexport default PWAInstaller;\n\nWhen a server function is called fetching will be set to true until the response is resolved.
When a server function is called a key with the name of the server function invoked will be set to true in the loading key until the response is resolved.
Any key you invoke on the loading object will always return a boolean instead of undefined for consistency.
When the server is emulating the client context for server-side rendering, every key of the loading object will always return false, saving multiple render cycles in performance.
import Nullstack from 'nullstack';\n\nclass Page extends Nullstack {\n\n static async save() {\n // ...\n }\n\n async submit() {\n await this.save();\n }\n \n render({worker}) {\n return (\n <form onsubmit={this.save}> \n {worker.fetching && \n <span> loading... </span>\n }\n <button disabled={worker.loading.save}> \n Save\n </button>\n </form>\n )\n }\n\n}\n\nexport default Page;\n\nYou can use the headers key to configure the headers that the worker will use when fetching a server function.
\n\n🔥 Headers will be ignored when a server function is called during the server-side rendering process.
\n
import Nullstack from 'nullstack';\n\nclass LoginPage extends Nullstack {\n\n // ...\n\n async submit({worker}) {\n // ...\n this.headers['Authorization'] = `Bearer ${token}`;\n // ...\n }\n\n static async authorize({request}) {\n const authorization = request.headers['Authorization'];\n // ...\n }\n \n // ...\n\n}\n\n\nexport default LoginPage;\n\n\n\n✨ Learn more about the server request and response
\n
worker.responsive and worker.online are set to false;worker.responsive and worker.online are set to false;Nullstack will install automatically your service worker if enabled is set to true with the following events:
installactivatefetchYou can override any of those events by creating a service-worker.js in the public folder;
\nIf any of the keywords above are found Nullstack will inject your function in the service worker code instead of the default.
\nFor convenience a context key is injected in the service worker self with the following keys:
workerprojectenvironmentfunction activate(event) {\n event.waitUntil(async function() {\n const cacheNames = await caches.keys();\n const cachesToDelete = cacheNames.filter(cacheName => cacheName !== self.context.environment.key);\n await Promise.all(cachesToDelete.map((cacheName) => caches.delete(cacheName)));\n if (self.registration.navigationPreload) {\n await self.registration.navigationPreload.enable();\n }\n self.clients.claim();\n }());\n}\n\nself.addEventListener('activate', activate);\n\n\n\n💡 The example above is extracted from the generated service worker and uses
\nself.context.environment.key
⚔ Learn how to deploy a Nullstack application.
\n","description":"The worker object is a proxy in the Nullstack Context available in both client and server and gives you granular control of your PWA behavior"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Context Service Worker - Nullstack","description":"The worker object is a proxy in the Nullstack Context available in both client and server and gives you granular control of your PWA behavior"}} \ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml deleted file mode 100644 index 889e3d3f..00000000 --- a/docs/sitemap.xml +++ /dev/null @@ -1 +0,0 @@ -A productive full-stack web framework should not force you to think about framework details.
-Nullstack takes control of its subclasses and generates a proxy for each instance.
-When you call anything on your class you are actually telling Nullstack what to do with the environment behind the scenes.
-This allows you to use vanilla javascript operations like assigning to a variable and see the reflection in the dom.
-You can mutate instance variables to update your application state.
-Functions are automatically bound to the instance proxy and can be passed as a reference to events.
-Events are declared like normal HTML attributes.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- increment() {
- this.count++;
- }
-
- render() {
- return (
- <button onclick={this.increment}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
---💡 Updates are made in batches, usually while awaiting async calls, so making multiple assignments have no performance costs!
-
You can shortcut events that are simple assignments by passing an object to the event.
-Each key of the object will be assigned to the instance.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render() {
- return (
- <button onclick={{count: this.count + 1}}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
-By default, events refer to this when you pass an object.
You can use the source attribute to define which object will receive the assignments.
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- render({params}) {
- return (
- <button source={params} onclick={{page: 1}}>
- First Page
- </button>
- )
- }
-
-}
-
-export default Paginator;
-
---✨ Learn more about context
-params.
--💡 If you do not declare a source to the event, Nullstack will inject a
-source={this}at transpile time in order to completely skip the runtime lookup process!
Attributes of the event target will be merged to the instance context and can be destructured in the function signature.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- increment({delta}) {
- this.count += delta;
- }
-
- render() {
- return (
- <button onclick={this.increment} delta={2}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
---💡 Any attribute with primitive value will be added to the DOM.
-
--✨ Consider using
-dataattributes to make your html valid.
The browser default behavior is prevented by default.
-You can opt-out of this by declaring a default attribute to the event element.
A reference to the original event is always merged with the function context.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- submit({event}) {
- event.preventDefault();
- }
-
- render() {
- return (
- <form onsubmit={this.submit} default>
- <button> Submit </button>
- </form>
- )
- }
-
-}
-
-export default Form;
-
-⚔ Learn about the full-stack lifecycle.
-A productive full-stack web framework should not force you to think about framework details.
-Nullstack takes control of its subclasses and generates a proxy for each instance.
-When you call anything on your class you are actually telling Nullstack what to do with the environment behind the scenes.
-This allows you to use vanilla javascript operations like assigning to a variable and see the reflection in the dom.
-You can mutate instance variables to update your application state.
-Functions are automatically bound to the instance proxy and can be passed as a reference to events.
-Events are declared like normal HTML attributes.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- increment() {
- this.count++;
- }
-
- render() {
- return (
- <button onclick={this.increment}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
---💡 Updates are made in batches, usually while awaiting async calls, so making multiple assignments have no performance costs!
-
You can shortcut events that are simple assignments by passing an object to the event.
-Each key of the object will be assigned to the instance.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- render() {
- return (
- <button onclick={{count: this.count + 1}}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
-By default, events refer to this when you pass an object.
You can use the source attribute to define which object will receive the assignments.
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- render({params}) {
- return (
- <button source={params} onclick={{page: 1}}>
- First Page
- </button>
- )
- }
-
-}
-
-export default Paginator;
-
---✨ Learn more about context
-params.
--💡 If you do not declare a source to the event, Nullstack will inject a
-source={this}at transpile time in order to completely skip the runtime lookup process!
Attributes of the event target will be merged to the instance context and can be destructured in the function signature.
-import Nullstack from 'nullstack';
-
-class Counter extends Nullstack {
-
- count = 0;
-
- increment({delta}) {
- this.count += delta;
- }
-
- render() {
- return (
- <button onclick={this.increment} delta={2}>
- {this.count}
- </button>
- )
- }
-
-}
-
-export default Counter;
-
---💡 Any attribute with primitive value will be added to the DOM.
-
--✨ Consider using
-dataattributes to make your html valid.
The browser default behavior is prevented by default.
-You can opt-out of this by declaring a default attribute to the event element.
A reference to the original event is always merged with the function context.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- submit({event}) {
- event.preventDefault();
- }
-
- render() {
- return (
- <form onsubmit={this.submit} default>
- <button> Submit </button>
- </form>
- )
- }
-
-}
-
-export default Form;
-
-⚔ Learn about the full-stack lifecycle.
-A productive full-stack web framework should not force you to think about framework details.
\nNullstack takes control of its subclasses and generates a proxy for each instance.
\nWhen you call anything on your class you are actually telling Nullstack what to do with the environment behind the scenes.
\nThis allows you to use vanilla javascript operations like assigning to a variable and see the reflection in the dom.
\nYou can mutate instance variables to update your application state.
\nFunctions are automatically bound to the instance proxy and can be passed as a reference to events.
\nEvents are declared like normal HTML attributes.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n increment() {\n this.count++;\n }\n \n render() {\n return (\n <button onclick={this.increment}> \n {this.count}\n </button>\n )\n }\n\n}\n\nexport default Counter;\n\n\n\n💡 Updates are made in batches, usually while awaiting async calls, so making multiple assignments have no performance costs!
\n
You can shortcut events that are simple assignments by passing an object to the event.
\nEach key of the object will be assigned to the instance.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n count = 0;\n \n render() {\n return (\n <button onclick={{count: this.count + 1}}> \n {this.count}\n </button>\n )\n }\n\n}\n\nexport default Counter;\n\nBy default, events refer to this when you pass an object.
You can use the source attribute to define which object will receive the assignments.
import Nullstack from 'nullstack';\n\nclass Paginator extends Nullstack {\n \n render({params}) {\n return (\n <button source={params} onclick={{page: 1}}> \n First Page\n </button>\n )\n }\n\n}\n\nexport default Paginator;\n\n\n\n✨ Learn more about context
\nparams.
\n\n💡 If you do not declare a source to the event, Nullstack will inject a
\nsource={this}at transpile time in order to completely skip the runtime lookup process!
Attributes of the event target will be merged to the instance context and can be destructured in the function signature.
\nimport Nullstack from 'nullstack';\n\nclass Counter extends Nullstack {\n\n count = 0;\n\n increment({delta}) {\n this.count += delta;\n }\n \n render() {\n return (\n <button onclick={this.increment} delta={2}> \n {this.count}\n </button>\n )\n }\n\n}\n\nexport default Counter;\n\n\n\n💡 Any attribute with primitive value will be added to the DOM.
\n
\n\n✨ Consider using
\ndataattributes to make your html valid.
The browser default behavior is prevented by default.
\nYou can opt-out of this by declaring a default attribute to the event element.
A reference to the original event is always merged with the function context.
\nimport Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n submit({event}) {\n event.preventDefault();\n }\n \n render() {\n return (\n <form onsubmit={this.submit} default>\n <button> Submit </button>\n </form>\n )\n }\n\n}\n\nexport default Form;\n\n⚔ Learn about the full-stack lifecycle.
\n","description":"A productive full-stack web framework should not force you to think about framework details"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Stateful Components - Nullstack","description":"A productive full-stack web framework should not force you to think about framework details"}} \ No newline at end of file diff --git a/docs/static-site-generation.html b/docs/static-site-generation.html deleted file mode 100644 index 1bc04475..00000000 --- a/docs/static-site-generation.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - -Use Nullstack to generate static websites for lightning-fast static applications using the full power of the Nullstack client without the need for a node.js back-end.
-Static sites are useful for read-only applications like blogs and documentation.
---💡 This documentation is actually a static site generated with Nullstack.
-
All the benefits of server-side rendering apply to static generated sites.
-You can generate a static website from your Nullstack application with the following npx command:
npx create-nullstatic-app
-
---🔥 You must be in a Nullstack project folder to run this command.
-
By default, it will create your Nullstatic application in the static folder.
-You can change the folder by passing it as an argument to the command:
-npx create-nullstatic-app docs
-
-The Nullstatic generator will run your application in production mode and crawl every link to an internal route it finds in your DOM.
---💡 Make sure to have the server production port free when you run this command.
-
The manifest.json and the contents of the public folder will be copied into the target folder.
-Besides generating raw HTML it will also generate a JSON file for each route with a copy of the state.
-On the first visit to your static application, HTML will be served and hydrated.
-On the subsequent requests, Nullstack will fetch the generated JSON and update the application state without ever reloading the page.
-This, in fact, gives you not only a static generated site, but a static generated API that feeds a Single Page Application with zero costs.
-You can add a script to your package.json to generate your static website in a custom folder:
-{
- "name": "nullstack.github.io",
- "version": "0.0.1",
- "description": "",
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "nullstack": "~0.9.0"
- },
- "scripts": {
- "start": "npx webpack --config node_modules/nullstack/webpack.config.js --mode=development --watch",
- "build": "npx webpack --config node_modules/nullstack/webpack.config.js --mode=production",
- "ssg": "npx create-nullstatic-app docs"
- }
-}
-
-
-Nullstatic only crawls your application up to the initiate resolution, further API requests triggered by events will be ignored.
Nullstatic will crawl a "/404" URL and generate both a "/404.html" and a "/404/index.html".
-⚔ Learn more about the service worker.
-Use Nullstack to generate static websites for lightning-fast static applications using the full power of the Nullstack client without the need for a node.js back-end.
-Static sites are useful for read-only applications like blogs and documentation.
---💡 This documentation is actually a static site generated with Nullstack.
-
All the benefits of server-side rendering apply to static generated sites.
-You can generate a static website from your Nullstack application with the following npx command:
npx create-nullstatic-app
-
---🔥 You must be in a Nullstack project folder to run this command.
-
By default, it will create your Nullstatic application in the static folder.
-You can change the folder by passing it as an argument to the command:
-npx create-nullstatic-app docs
-
-The Nullstatic generator will run your application in production mode and crawl every link to an internal route it finds in your DOM.
---💡 Make sure to have the server production port free when you run this command.
-
The manifest.json and the contents of the public folder will be copied into the target folder.
-Besides generating raw HTML it will also generate a JSON file for each route with a copy of the state.
-On the first visit to your static application, HTML will be served and hydrated.
-On the subsequent requests, Nullstack will fetch the generated JSON and update the application state without ever reloading the page.
-This, in fact, gives you not only a static generated site, but a static generated API that feeds a Single Page Application with zero costs.
-You can add a script to your package.json to generate your static website in a custom folder:
-{
- "name": "nullstack.github.io",
- "version": "0.0.1",
- "description": "",
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "nullstack": "~0.9.0"
- },
- "scripts": {
- "start": "npx webpack --config node_modules/nullstack/webpack.config.js --mode=development --watch",
- "build": "npx webpack --config node_modules/nullstack/webpack.config.js --mode=production",
- "ssg": "npx create-nullstatic-app docs"
- }
-}
-
-
-Nullstatic only crawls your application up to the initiate resolution, further API requests triggered by events will be ignored.
Nullstatic will crawl a "/404" URL and generate both a "/404.html" and a "/404/index.html".
-⚔ Learn more about the service worker.
-Use Nullstack to generate static websites for lightning-fast static applications using the full power of the Nullstack client without the need for a node.js back-end.
\nStatic sites are useful for read-only applications like blogs and documentation.
\n\n\n💡 This documentation is actually a static site generated with Nullstack.
\n
All the benefits of server-side rendering apply to static generated sites.
\nYou can generate a static website from your Nullstack application with the following npx command:
npx create-nullstatic-app\n\n\n\n🔥 You must be in a Nullstack project folder to run this command.
\n
By default, it will create your Nullstatic application in the static folder.
\nYou can change the folder by passing it as an argument to the command:
\nnpx create-nullstatic-app docs\n\nThe Nullstatic generator will run your application in production mode and crawl every link to an internal route it finds in your DOM.
\n\n\n💡 Make sure to have the server production port free when you run this command.
\n
The manifest.json and the contents of the public folder will be copied into the target folder.
\nBesides generating raw HTML it will also generate a JSON file for each route with a copy of the state.
\nOn the first visit to your static application, HTML will be served and hydrated.
\nOn the subsequent requests, Nullstack will fetch the generated JSON and update the application state without ever reloading the page.
\nThis, in fact, gives you not only a static generated site, but a static generated API that feeds a Single Page Application with zero costs.
\nYou can add a script to your package.json to generate your static website in a custom folder:
\n{\n \"name\": \"nullstack.github.io\",\n \"version\": \"0.0.1\",\n \"description\": \"\",\n \"author\": \"\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"nullstack\": \"~0.9.0\"\n },\n \"scripts\": {\n \"start\": \"npx webpack --config node_modules/nullstack/webpack.config.js --mode=development --watch\",\n \"build\": \"npx webpack --config node_modules/nullstack/webpack.config.js --mode=production\",\n \"ssg\": \"npx create-nullstatic-app docs\"\n }\n}\n\n\nNullstatic only crawls your application up to the initiate resolution, further API requests triggered by events will be ignored.
Nullstatic will crawl a "/404" URL and generate both a "/404.html" and a "/404/index.html".
\n⚔ Learn more about the service worker.
\n","description":"Use Nullstack to generate static websites for lightning-fast static applications using the full power of Nullstack without the need for a node.js back-end"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Static Site Generation - Nullstack","description":"Use Nullstack to generate static websites for lightning-fast static applications using the full power of Nullstack without the need for a node.js back-end"}} \ No newline at end of file diff --git a/docs/styles.html b/docs/styles.html deleted file mode 100644 index a481acda..00000000 --- a/docs/styles.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - -Using styles with Nullstack is as simple as importing a style file.
-Nullstack comes with a SASS loader by default, but you can still use vanilla CSS.
---✨ It's a good practice to import a file with the same name as the component.
-
import Nullstack from 'nullstack';
-import './Header.scss';
-
-class Header extends Nullstack {
- // ...
-}
-
-export default Header;
-
-In production mode Nullstack uses PurceCSS, which cleans your client.css file, but has some gotchas.
---✨ Learn more about safelisting your css
-
⚔ Learn about the NJS file extension.
-Using styles with Nullstack is as simple as importing a style file.
-Nullstack comes with a SASS loader by default, but you can still use vanilla CSS.
---✨ It's a good practice to import a file with the same name as the component.
-
import Nullstack from 'nullstack';
-import './Header.scss';
-
-class Header extends Nullstack {
- // ...
-}
-
-export default Header;
-
-In production mode Nullstack uses PurceCSS, which cleans your client.css file, but has some gotchas.
---✨ Learn more about safelisting your css
-
⚔ Learn about the NJS file extension.
-Using styles with Nullstack is as simple as importing a style file.
\nNullstack comes with a SASS loader by default, but you can still use vanilla CSS.
\n\n\n✨ It's a good practice to import a file with the same name as the component.
\n
import Nullstack from 'nullstack';\nimport './Header.scss';\n\nclass Header extends Nullstack {\n // ...\n}\n\nexport default Header;\n\nIn production mode Nullstack uses PurceCSS, which cleans your client.css file, but has some gotchas.
\n\n\n✨ Learn more about safelisting your css
\n
⚔ Learn about the NJS file extension.
\n","description":"Using styles with Nullstack is as simple as importing a style file"},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Styles - Nullstack","description":"Using styles with Nullstack is as simple as importing a style file"}} \ No newline at end of file diff --git a/docs/thumbnail-en-us-1.webp b/docs/thumbnail-en-us-1.webp deleted file mode 100644 index 63a124f1..00000000 Binary files a/docs/thumbnail-en-us-1.webp and /dev/null differ diff --git a/docs/thumbnail-en-us-2.webp b/docs/thumbnail-en-us-2.webp deleted file mode 100644 index 74cd6e31..00000000 Binary files a/docs/thumbnail-en-us-2.webp and /dev/null differ diff --git a/docs/thumbnail-en-us-3.webp b/docs/thumbnail-en-us-3.webp deleted file mode 100644 index 8d9bd111..00000000 Binary files a/docs/thumbnail-en-us-3.webp and /dev/null differ diff --git a/docs/thumbnail-pt-br-1.webp b/docs/thumbnail-pt-br-1.webp deleted file mode 100644 index f924404e..00000000 Binary files a/docs/thumbnail-pt-br-1.webp and /dev/null differ diff --git a/docs/thumbnail-pt-br-2.webp b/docs/thumbnail-pt-br-2.webp deleted file mode 100644 index 2c1272a7..00000000 Binary files a/docs/thumbnail-pt-br-2.webp and /dev/null differ diff --git a/docs/thumbnail-pt-br-3.webp b/docs/thumbnail-pt-br-3.webp deleted file mode 100644 index a9b32939..00000000 Binary files a/docs/thumbnail-pt-br-3.webp and /dev/null differ diff --git a/docs/two-way-bindings.html b/docs/two-way-bindings.html deleted file mode 100644 index 91f529f3..00000000 --- a/docs/two-way-bindings.html +++ /dev/null @@ -1,287 +0,0 @@ - - - - - -Big chunks of code in a progressive web application is dedicated to reacting to user input.
-The process of controlling user input can be broken into 3 tedious steps:
-The last step might include typecasting and other value treatments.
-This process in which you manually do all these steps is called one-way binding, it is the default in many frameworks, and is possible in Nullstack.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- string = '';
-
- updateString({event}) {
- this.string = event.target.value;
- }
-
- updateNumber({event}) {
- this.number = parseInt(event.target.value);
- }
-
- render() {
- return (
- <form>
- <input
- type="text"
- name="string"
- value={this.string}
- oninput={this.updateString}
- />
- <input
- type="number"
- name="number"
- value={this.number}
- oninput={this.updateNumber}
- />
- </form>
- )
- }
-
-}
-
-export default Form;
-
-Bind reduces drastically the amount of glue code you have to type in your application.
-You can shortcut setting a value, name, and event with the bind attribute.
--💡 Nullstack will simply replace
-bindwith thevalue,name, and event under the hood.
Bind will generate an event that automatically typecasts to the previous primitive type the value was.
-You can pass any variable to the bind as long as its parent object is mentioned.
import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- string = '';
-
- render() {
- return (
- <form>
- <input type="text" bind={this.string} />
- <input type="number" bind={this.number} />
- </form>
- )
- }
-
-}
-
-export default Form;
-
-The following events are set for each type of input:
-onclick for inputs with the checkbox typeoninput for other inputs and textareasonchange for anything elseYou can still declare an attribute with the same bound event.
-Events will not override the bound event, instead, it will be executed after bind mutates the variable.
-The new value will be merged into the function context.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- name = '';
-
- compare({value}) {
- this.name === value;
- }
-
- render() {
- return (
- <input bind={this.name} oninput={this.compare} />
- )
- }
-
-}
-
-export default Form;
-
-Bind can take a source attribute as well.
--💡 If you do not declare a source to the bind, Nullstack will inject a
-source={this}at transpile time in order to completely skip the runtime lookup process!
If you declare a source, bind must be a string with the name of the key that will be mutated.
The source will be merged into the context of events.
-import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- validate({source, params}) {
- if(!source.page) {
- params.page = '1';
- }
- }
-
- render({params}) {
- return (
- <input
- source={params}
- bind="page"
- oninput={this.validate}
- />
- )
- }
-
-}
-
-export default Paginator;
-
---💡 Binding by reference is possible because all binds are converted to the format above at transpile time.
-
Any object that responds to a key call with "[]" can be bound.
-The name attribute can be overwritten.
import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- boolean = true;
- character = 'a';
- text = 'aaaa';
-
- object = {count: 1};
- array = ['a', 'b', 'c'];
-
- render({params}) {
- return (
- <div>
- <input bind={this.number} />
- <textarea bind={this.text} />
- <select bind={this.character}>
- {this.array.map((character) => <option>{character}</option>)}
- </select>
- <select bind={this.boolean} name="boolean-select">
- <option value={true}>true</option>
- <option value={false}>false</option>
- </select>
- <input bind={this.boolean} type="checkbox" />
- <input bind={this.object.count} />
- {this.array.map((value, index) => (
- <input bind={this.array[index]} />
- ))}
- <input bind={params.page} />
- </div>
- )
- }
-
-}
-
-export default Form;
-
-You can use object events alongside bind normally.
The event will run after the variable is mutated.
-The event will share the bind source.
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- render({params}) {
- return (
- <input bind={params.filter} oninput={{page: 1}} />
- )
- }
-
-}
-
-export default Paginator;
-
-You can create your own bindable component by receiving the attributes that bind generates.
You must respond by calling onchange with a value key.
You can also merge any other keys you wish to send to the component user.
-class CurrencyInput extends Nullstack {
-
- parse({event, onchange}) {
- const normalized = event.target.value.replace(',', '').padStart(3, '0');
- const whole = (parseInt(normalized.slice(0,-2)) || 0).toString();
- const decimal = normalized.slice(normalized.length - 2);
- const value = parseFloat(whole+'.'+decimal);
- const bringsHappyness = value >= 1000000;
- onchange({value, bringsHappyness});
- }
-
- render({value, name}) {
- const formatted = value.toFixed(2).replace('.', ',');
- return <input name={name} value={formatted} oninput={this.parse} />
- }
-
-}
-
-import Nullstack from 'nullstack';
-import CurrencyInput from './CurrencyInput';
-
-class Form extends Nullstack {
-
- balance = 0;
-
- render() {
- return (
- <CurrencyInput bind={this.balance} />
- )
- }
-
-}
-
-export default Form;
-
---🎉 Congratulations!. You are done with the core concepts!
-
⚔ Learn about the application startup.
-Big chunks of code in a progressive web application is dedicated to reacting to user input.
-The process of controlling user input can be broken into 3 tedious steps:
-The last step might include typecasting and other value treatments.
-This process in which you manually do all these steps is called one-way binding, it is the default in many frameworks, and is possible in Nullstack.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- string = '';
-
- updateString({event}) {
- this.string = event.target.value;
- }
-
- updateNumber({event}) {
- this.number = parseInt(event.target.value);
- }
-
- render() {
- return (
- <form>
- <input
- type="text"
- name="string"
- value={this.string}
- oninput={this.updateString}
- />
- <input
- type="number"
- name="number"
- value={this.number}
- oninput={this.updateNumber}
- />
- </form>
- )
- }
-
-}
-
-export default Form;
-
-Bind reduces drastically the amount of glue code you have to type in your application.
-You can shortcut setting a value, name, and event with the bind attribute.
--💡 Nullstack will simply replace
-bindwith thevalue,name, and event under the hood.
Bind will generate an event that automatically typecasts to the previous primitive type the value was.
-You can pass any variable to the bind as long as its parent object is mentioned.
import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- string = '';
-
- render() {
- return (
- <form>
- <input type="text" bind={this.string} />
- <input type="number" bind={this.number} />
- </form>
- )
- }
-
-}
-
-export default Form;
-
-The following events are set for each type of input:
-onclick for inputs with the checkbox typeoninput for other inputs and textareasonchange for anything elseYou can still declare an attribute with the same bound event.
-Events will not override the bound event, instead, it will be executed after bind mutates the variable.
-The new value will be merged into the function context.
-import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- name = '';
-
- compare({value}) {
- this.name === value;
- }
-
- render() {
- return (
- <input bind={this.name} oninput={this.compare} />
- )
- }
-
-}
-
-export default Form;
-
-Bind can take a source attribute as well.
--💡 If you do not declare a source to the bind, Nullstack will inject a
-source={this}at transpile time in order to completely skip the runtime lookup process!
If you declare a source, bind must be a string with the name of the key that will be mutated.
The source will be merged into the context of events.
-import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- validate({source, params}) {
- if(!source.page) {
- params.page = '1';
- }
- }
-
- render({params}) {
- return (
- <input
- source={params}
- bind="page"
- oninput={this.validate}
- />
- )
- }
-
-}
-
-export default Paginator;
-
---💡 Binding by reference is possible because all binds are converted to the format above at transpile time.
-
Any object that responds to a key call with "[]" can be bound.
-The name attribute can be overwritten.
import Nullstack from 'nullstack';
-
-class Form extends Nullstack {
-
- number = 1;
- boolean = true;
- character = 'a';
- text = 'aaaa';
-
- object = {count: 1};
- array = ['a', 'b', 'c'];
-
- render({params}) {
- return (
- <div>
- <input bind={this.number} />
- <textarea bind={this.text} />
- <select bind={this.character}>
- {this.array.map((character) => <option>{character}</option>)}
- </select>
- <select bind={this.boolean} name="boolean-select">
- <option value={true}>true</option>
- <option value={false}>false</option>
- </select>
- <input bind={this.boolean} type="checkbox" />
- <input bind={this.object.count} />
- {this.array.map((value, index) => (
- <input bind={this.array[index]} />
- ))}
- <input bind={params.page} />
- </div>
- )
- }
-
-}
-
-export default Form;
-
-You can use object events alongside bind normally.
The event will run after the variable is mutated.
-The event will share the bind source.
import Nullstack from 'nullstack';
-
-class Paginator extends Nullstack {
-
- render({params}) {
- return (
- <input bind={params.filter} oninput={{page: 1}} />
- )
- }
-
-}
-
-export default Paginator;
-
-You can create your own bindable component by receiving the attributes that bind generates.
You must respond by calling onchange with a value key.
You can also merge any other keys you wish to send to the component user.
-class CurrencyInput extends Nullstack {
-
- parse({event, onchange}) {
- const normalized = event.target.value.replace(',', '').padStart(3, '0');
- const whole = (parseInt(normalized.slice(0,-2)) || 0).toString();
- const decimal = normalized.slice(normalized.length - 2);
- const value = parseFloat(whole+'.'+decimal);
- const bringsHappyness = value >= 1000000;
- onchange({value, bringsHappyness});
- }
-
- render({value, name}) {
- const formatted = value.toFixed(2).replace('.', ',');
- return <input name={name} value={formatted} oninput={this.parse} />
- }
-
-}
-
-import Nullstack from 'nullstack';
-import CurrencyInput from './CurrencyInput';
-
-class Form extends Nullstack {
-
- balance = 0;
-
- render() {
- return (
- <CurrencyInput bind={this.balance} />
- )
- }
-
-}
-
-export default Form;
-
---🎉 Congratulations!. You are done with the core concepts!
-
⚔ Learn about the application startup.
-Big chunks of code in a progressive web application is dedicated to reacting to user input.
\nThe process of controlling user input can be broken into 3 tedious steps:
\nThe last step might include typecasting and other value treatments.
\nThis process in which you manually do all these steps is called one-way binding, it is the default in many frameworks, and is possible in Nullstack.
\nimport Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n number = 1;\n string = '';\n\n updateString({event}) {\n this.string = event.target.value;\n }\n\n updateNumber({event}) {\n this.number = parseInt(event.target.value);\n }\n \n render() {\n return (\n <form>\n <input\n type=\"text\"\n name=\"string\"\n value={this.string}\n oninput={this.updateString}\n />\n <input\n type=\"number\"\n name=\"number\"\n value={this.number}\n oninput={this.updateNumber}\n />\n </form>\n )\n }\n\n}\n\nexport default Form;\n\nBind reduces drastically the amount of glue code you have to type in your application.
\nYou can shortcut setting a value, name, and event with the bind attribute.
\n\n💡 Nullstack will simply replace
\nbindwith thevalue,name, and event under the hood.
Bind will generate an event that automatically typecasts to the previous primitive type the value was.
\nYou can pass any variable to the bind as long as its parent object is mentioned.
import Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n number = 1;\n string = '';\n \n render() {\n return (\n <form>\n <input type=\"text\" bind={this.string} />\n <input type=\"number\" bind={this.number} />\n </form>\n )\n }\n\n}\n\nexport default Form;\n\nThe following events are set for each type of input:
\nonclick for inputs with the checkbox typeoninput for other inputs and textareasonchange for anything elseYou can still declare an attribute with the same bound event.
\nEvents will not override the bound event, instead, it will be executed after bind mutates the variable.
\nThe new value will be merged into the function context.
\nimport Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n name = '';\n\n compare({value}) {\n this.name === value;\n }\n \n render() {\n return (\n <input bind={this.name} oninput={this.compare} />\n )\n }\n\n}\n\nexport default Form;\n\nBind can take a source attribute as well.
\n\n💡 If you do not declare a source to the bind, Nullstack will inject a
\nsource={this}at transpile time in order to completely skip the runtime lookup process!
If you declare a source, bind must be a string with the name of the key that will be mutated.
The source will be merged into the context of events.
\nimport Nullstack from 'nullstack';\n\nclass Paginator extends Nullstack {\n\n validate({source, params}) {\n if(!source.page) {\n params.page = '1';\n }\n }\n\n render({params}) {\n return (\n <input \n source={params}\n bind=\"page\"\n oninput={this.validate}\n />\n )\n }\n\n}\n\nexport default Paginator;\n\n\n\n💡 Binding by reference is possible because all binds are converted to the format above at transpile time.
\n
Any object that responds to a key call with "[]" can be bound.
\nThe name attribute can be overwritten.
import Nullstack from 'nullstack';\n\nclass Form extends Nullstack {\n\n number = 1;\n boolean = true;\n character = 'a';\n text = 'aaaa';\n \n object = {count: 1};\n array = ['a', 'b', 'c'];\n\n render({params}) {\n return (\n <div>\n <input bind={this.number} />\n <textarea bind={this.text} />\n <select bind={this.character}>\n {this.array.map((character) => <option>{character}</option>)}\n </select>\n <select bind={this.boolean} name=\"boolean-select\">\n <option value={true}>true</option>\n <option value={false}>false</option>\n </select>\n <input bind={this.boolean} type=\"checkbox\" />\n <input bind={this.object.count} />\n {this.array.map((value, index) => (\n <input bind={this.array[index]} />\n ))}\n <input bind={params.page} />\n </div>\n )\n }\n\n}\n\nexport default Form;\n\nYou can use object events alongside bind normally.
The event will run after the variable is mutated.
\nThe event will share the bind source.
import Nullstack from 'nullstack';\n\nclass Paginator extends Nullstack {\n\n render({params}) {\n return (\n <input bind={params.filter} oninput={{page: 1}} />\n )\n }\n\n}\n\nexport default Paginator;\n\nYou can create your own bindable component by receiving the attributes that bind generates.
You must respond by calling onchange with a value key.
You can also merge any other keys you wish to send to the component user.
\nclass CurrencyInput extends Nullstack {\n\n parse({event, onchange}) {\n const normalized = event.target.value.replace(',', '').padStart(3, '0');\n const whole = (parseInt(normalized.slice(0,-2)) || 0).toString();\n const decimal = normalized.slice(normalized.length - 2);\n const value = parseFloat(whole+'.'+decimal);\n const bringsHappyness = value >= 1000000;\n onchange({value, bringsHappyness});\n }\n\n render({value, name}) {\n const formatted = value.toFixed(2).replace('.', ',');\n return <input name={name} value={formatted} oninput={this.parse} />\n }\n\n}\n\nimport Nullstack from 'nullstack';\nimport CurrencyInput from './CurrencyInput';\n\nclass Form extends Nullstack {\n\n balance = 0;\n\n render() {\n return (\n <CurrencyInput bind={this.balance} />\n )\n }\n\n}\n\nexport default Form;\n\n\n\n🎉 Congratulations!. You are done with the core concepts!
\n
⚔ Learn about the application startup.
\n","description":"Bind reduces drastically the amount of glue code you have to type in your application."},"n-0-0-13":{},"n-0-0-15":{},"n-0-0-16":{"locale":"en-US","i18n":{"nullachan":{"alt":"Nulla-Chan","title":"Nulla-Chan: Nullstack's official waifu"},"links":[{"title":"YouTube","href":"https://www.youtube.com/channel/UCUNPaxoppH3lu6JTrUX78Ww"},{"title":"Twitter","href":"https://twitter.com/nullstackapp"},{"title":"GitHub","href":"https://github.com/nullstack"}]}}}, "page": {"image":"/image-1200x630.png","status":200,"title":"Two-Way Binding - Nullstack","description":"Bind reduces drastically the amount of glue code you have to type in your application."}} \ No newline at end of file diff --git a/docs/waifu.html b/docs/waifu.html deleted file mode 100644 index b4435386..00000000 --- a/docs/waifu.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - -
Nullstack's official waifu
A sweet and shy perfect waifu, is always hyperfocused in her studies but somehow distracted at the same time.
She is always cheerful... until she has to face glue code or sees a post telling her which tech she should use.

Nullstack's official waifu
A sweet and shy perfect waifu, is always hyperfocused in her studies but somehow distracted at the same time.
She is always cheerful... until she has to face glue code or sees a post telling her which tech she should use.
Count: {this.value}
+ } + +} + +export default Counter; +``` + +You can access any methods and instance variables from **counter** instance on **AnyOtherComponent**: + +```jsx +import Nullstack from 'nullstack'; + +class AnyOtherComponent extends Nullstack { + + render({ instances }) { + return ( + + ) + } + +} + +export default AnyOtherComponent; +``` + +The use of `instances` unlocks unlimited custom behaviors like: + +- A notification icon at the navbar that can be updated from other components at certain actions +- A *toast* component that can be invoked from anywhere in your application +- A *store* system with custom dispatch methods similar to Redux +- Something we haven't even imagined, dream on and post your ideas on GitHub! \ No newline at end of file diff --git a/i18n/en-US/articles/context-page.md b/i18n/en-US/articles/context-page.md index 929826b2..351786e9 100644 --- a/i18n/en-US/articles/context-page.md +++ b/i18n/en-US/articles/context-page.md @@ -133,8 +133,4 @@ class Application extends Nullstack { export default Application; ``` -> 🔥 Assigning to the `status` key during the [single-page application](/full-stack-lifecycle) mode will have no effect. - -## Next step - -⚔ Learn about the [context `project`](/context-project). \ No newline at end of file +> 🔥 Assigning to the `status` key during the [single-page application](/full-stack-lifecycle) mode will have no effect. \ No newline at end of file diff --git a/i18n/en-US/articles/context-project.md b/i18n/en-US/articles/context-project.md index 9f691249..12ac9f2d 100644 --- a/i18n/en-US/articles/context-project.md +++ b/i18n/en-US/articles/context-project.md @@ -13,18 +13,16 @@ It gives you information about the app manifest and some metatags. `project` keys will be used to generate metatags during server-side rendering and must be assigned before [`initiate`](/full-stack-lifecycle) is resolved. -`project` keys will be used to generate the app **manifest** and should be set during the [application startup](/application-startup). +`project` keys will be used to generate the app **manifest**. -The `disallow` key will be used to generate the **robots.txt** and should be set during the [application startup](/application-startup). +The `disallow` key will be used to generate the **robots.txt**. -`project` keys are frozen after the [application startup](/application-startup). +The following keys are available in the object and supported as environment variables as follows: -The following keys are available in the object: - -- **domain**: `string` -- **name**: `string` -- **shortName**: `string` -- **color**: `string` +- **domain**: `string` (`NULLSTACK_PROJECT_DOMAIN`) +- **name**: `string` (`NULLSTACK_PROJECT_NAME`) +- **shortName**: `string` (`NULLSTACK_PROJECT_SHORT_NAME`) +- **color**: `string` (`NULLSTACK_PROJECT_COLOR`) - **backgroundColor**: `string` - **type**: `string` - **display**: `string` @@ -35,12 +33,14 @@ The following keys are available in the object: - **favicon**: `string` (relative or absolute url) - **disallow**: `string array` (relative paths) - **sitemap**: `boolean` or `string` (relative or absolute url) -- **cdn**: `string` (absolute url) -- **protocol**: `string` (http or https) +- **cdn**: `string` (`NULLSTACK_PROJECT_CDN`) +- **protocol**: `string` (`NULLSTACK_PROJECT_PROTOCOL`) Besides `domain`, `name` and `color` all other keys have sensible defaults generated based on the application scope. -If you do not declare the `icons` key, Nullstack will scan any icons with the name following the pattern "icon-[WIDTH]x[HEIGHT].png" in your public folder. +If you do not declare the `icons` key, Nullstack will scan any icons with the name following the pattern "icon-[WIDTH]x[HEIGHT].png" in your **public** folder. + +The `head` meta tag `apple-touch-icon` will be set to your `icon-180x180.png` file. If the `sitemap` key is set to true your **robots.txt** file will point the sitemap to `https://${project.domain}/sitemap.xml`. @@ -49,32 +49,46 @@ The `cdn` key will prefix your asset bundles and will be available in the contex The `protocol` key is "http" in development mode and "https" in production mode by default. ```jsx +// server.js import Nullstack from 'nullstack'; +import Application from './src/Application'; + +const context = Nullstack.start(Application); + +context.start = function() { + const { project } = context; + project.name = 'Nullstack'; + project.shortName = 'Nullstack'; + project.domain = 'nullstack.app'; + project.color = '#d22365'; + project.backgroundColor = '#d22365'; + project.type = 'website'; + project.display = 'standalone'; + project.orientation = 'portrait'; + project.scope = '/'; + project.root = '/'; + project.icons = { + '72': '/icon-72x72.png', + '128': '/icon-128x128.png', + '512': '/icon-512x512.png' + }; + project.favicon = '/favicon.png'; + project.disallow = ['/admin']; + project.sitemap = true; + project.cdn = 'cdn.nullstack.app'; + project.protocol = 'https'; +} -class Application extends Nullstack { +export default context; +``` - static async start({project}) { - project.name = 'Nullstack'; - project.shortName = 'Nullstack'; - project.domain = 'nullstack.app'; - project.color = '#d22365'; - project.backgroundColor = '#d22365'; - project.type = 'website'; - project.display = 'standalone'; - project.orientation = 'portrait'; - project.scope = '/'; - project.root = '/'; - project.icons = { - '72': '/icon-72x72.png', - '128': '/icon-128x128.png', - '512': '/icon-512x512.png' - }; - project.favicon = '/favicon.png'; - project.disallow = ['/admin']; - project.sitemap = true; - project.cdn = 'cdn.nullstack.app'; - project.protocol = 'https'; - } +> More about the `context.start` at [application startup](/application-startup) + +```jsx +// src/Application.njs +import Nullstack from 'nullstack'; + +class Application extends Nullstack { prepare({project, page}) { page.title = project.name; @@ -85,8 +99,4 @@ class Application extends Nullstack { export default Application; ``` -> 💡 You can override the automatically generated **manifest.json** and **robots.txt** by serving your own file from the **public** folder - -## Next step - -⚔ Learn about the [context `settings`](/context-settings). \ No newline at end of file +> 💡 You can override the automatically generated **manifest.json** and **robots.txt** by serving your own file from the **public** folder \ No newline at end of file diff --git a/i18n/en-US/articles/context-secrets.md b/i18n/en-US/articles/context-secrets.md index 8869db0b..3c52fc79 100644 --- a/i18n/en-US/articles/context-secrets.md +++ b/i18n/en-US/articles/context-secrets.md @@ -10,31 +10,32 @@ description: The secrets object is a proxy in the Nullstack Context available in You can use it to configure your application with private information. -`secrets` keys are frozen after the [application startup](/application-startup). +You can assign any keys with any type to the object. -The following keys are available in the object: +You can assign keys to `secrets` dynamically based on current environment using [`context.environment`](/context-environment). -- **development**: `object` -- **production**: `object` -- **[anySetting]**: `any` +```jsx +// server.js +import Nullstack from 'nullstack'; +import Application from './src/Application'; -You can assign keys to `development` or `production` keys in order to have different secrets per [environment](/context-environment). +const context = Nullstack.start(Application); -If you assign a key directly to the `secrets` object it will be available in both environments. +context.start = function() { + const { secrets, environment } = context; + secrets.endpoint = 'https://domain.com/api'; + secrets.privateKey = environment.development ? 'DEV_API_KEY' : 'PROD_API_KEY'; +} -When reading from a key you must read directly from the `secrets` object and Nullstack will return the best-suited value for that [environment](/context-environment). +export default context; +``` ```jsx +// src/Application.njs import Nullstack from 'nullstack'; class Application extends Nullstack { - static async start({secrets}) { - secrets.development.privateKey = 'SANDBOX_API_KEY'; - secrets.production.privateKey = 'PRODUCTION_API_KEY'; - secrets.endpoint = 'https://domain.com/api'; - } - static async fetchFromApi({secrets}) { const response = await fetch(secrets.endpoint, { headers: { @@ -49,10 +50,6 @@ class Application extends Nullstack { export default Application; ``` -Any environment key starting with NULLSTACK_SECRETS_ will be mapped to the secrets in that environment. - -> 🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY will be mapped to `secrets.privateKey` - -## Next step +Any environment variable starting with NULLSTACK_SECRETS_ will be mapped to the `secrets` in that environment. -⚔ Learn about the [instance self](/instance-self). \ No newline at end of file +> 🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY will be mapped to `secrets.privateKey` \ No newline at end of file diff --git a/i18n/en-US/articles/context-settings.md b/i18n/en-US/articles/context-settings.md index 959a9f0b..fb45ae00 100644 --- a/i18n/en-US/articles/context-settings.md +++ b/i18n/en-US/articles/context-settings.md @@ -11,31 +11,32 @@ description: The settings object is a proxy in the Nullstack Context available i You can use it to configure your application with public information. -`settings` keys are frozen after the [application startup](/application-startup). +You can assign any keys with any type to the object. -The following keys are available in the object: +You can assign keys to `settings` dynamically based on current environment using [`context.environment`](/context-environment). -- **development**: `object` -- **production**: `object` -- **[anySetting]**: `any` +```jsx +// server.js +import Nullstack from 'nullstack'; +import Application from './src/Application'; -You can assign keys to `development` or `production` keys in order to have different settings per [environment](/context-environment). +const context = Nullstack.start(Application); -If you assign a key directly to the `settings` object it will be available in both environments. +context.start = function() { + const { settings, environment } = context; + settings.endpoint = 'https://domain.com/api'; + settings.publicKey = environment.development ? 'DEV_API_KEY' : 'PROD_API_KEY'; +} -When reading from a key you must read directly from the `settings` object and Nullstack will return the best-suited value for that [environment](/context-environment). +export default context; +``` ```jsx +// src/Application.njs import Nullstack from 'nullstack'; class Application extends Nullstack { - static async start({settings}) { - settings.development.publicKey = 'SANDBOX_API_KEY'; - settings.production.publicKey = 'PRODUCTION_API_KEY'; - settings.endpoint = 'https://domain.com/api'; - } - async hydrate({settings}) { const response = await fetch(settings.endpoint, { headers: { @@ -50,10 +51,6 @@ class Application extends Nullstack { export default Application; ``` -Any environment key starting with NULLSTACK_SETTINGS_ will be mapped to the settings in that environment. - -> 🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY will be mapped to `settings.publicKey` - -## Next step +Any environment variable starting with NULLSTACK_SETTINGS_ will be mapped to the `settings` in that environment. -⚔ Learn about the [context `secrets`](/context-secrets). \ No newline at end of file +> 🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY will be mapped to `settings.publicKey` \ No newline at end of file diff --git a/i18n/en-US/articles/context.md b/i18n/en-US/articles/context.md index 71313c22..dd39286f 100644 --- a/i18n/en-US/articles/context.md +++ b/i18n/en-US/articles/context.md @@ -34,10 +34,9 @@ These are the information that the framework makes available to you by default. - [`response`](/server-request-and-response#request-and-response) - [`secrets`](/context-secrets) -### The available instance client keys are: +### The key available only in client: -- [`self`](/instance-self) -- [`children`](/renderable-components#components-with-children) +- [`instances`](/context-instances) ## 2 - Application Context @@ -45,7 +44,7 @@ When you set a key to the context it will be available for destructuring at any Updating a key in the context causes the application to re-render automatically. -You can think of this as a single concept to replace **stores**, **contexts**, **services**, and **reducers** at the same time using the dependency injection pattern with vanilla javascript objects instead. +You can think of this as a single concept to replace **stores**, **contexts**, **services**, and **reducers** at the same time using the dependency injection pattern with vanilla JavaScript objects instead. ```jsx import Nullstack from 'nullstack'; @@ -82,7 +81,7 @@ import Counter from './Counter'; class Application extends Nullstack { - static async start(context) { + prepare(context) { context.totalCount = 0; } @@ -101,7 +100,11 @@ export default Application; ## 3 - Component Context -This one contains the attributes you declare in your tag, including [`data`](/context-data). +This one contains the attributes you declare in your tag, and including: + +- [`data`](/context-data) +- [`self`](/instance-self) +- [`children`](/jsx-elements#components-with-children) If the attribute is declared in a component tag every function of that component will have access to that attribute in its context. @@ -180,8 +183,4 @@ class Counter extends Nullstack { } export default Counter; -``` - -## Next step - -⚔ Learn about [routes and params](/routes-and-params). \ No newline at end of file +``` \ No newline at end of file diff --git a/i18n/en-US/articles/frequently-asked-questions.md b/i18n/en-US/articles/frequently-asked-questions.md new file mode 100644 index 00000000..a1627f6b --- /dev/null +++ b/i18n/en-US/articles/frequently-asked-questions.md @@ -0,0 +1,63 @@ +--- +title: Frequently Asked Questions +description: Nullstack is an isomorphic JavaScript framework that allows developers to build Full Stack applications while staying focused on the product features, and solving the user problems, rather than spending a significant amount of their time worrying about layers of abstraction and choosing which tools make them look fancy +--- + +## What is feature-driven? +It means that every component is a full feature in itself, but it is up to you to decide how to break features down. As an example, you could have a "BlogPost" component or you could have a Blog a Post a Comment, and a Like component and they are nested into each other, heck you could even have an entire e-commerce application be a top-level component imported in another application, that's the beauty of full stack components. + +In the case of a Like button for instance, you would have the server functions to load the number of likes that item has, a render function to show your likes, and an event that triggers a server function to save your like, all in a single file if you want, the main reasoning for this architecture is that the project manager's tickets, the UX and the code look pretty much the same. + +*- But my bootcamp teacher said I need at least 3 layers of abstraction to be a good developer, can I do that in Nullstack?* + +Yes you can, Nullstack is a big foot-gun you can shoot your own foot in your favorite style, just ask for the permission of an adult first. + +## Is it a react framework? +Nope, but it uses JSX. Nullstack does not use hooks, instead, it aims to keep JavaScript's natural flow, but makes it reactive. Fun fact tho, Nullstack actually started as a react framework that just aimed to add server functions to the components, but eventually, I found that sticking to that model was limiting our creativity. + +## Why did you build another framework? +That wasn't the original intention, We were actually trying to build a coffee shop, but We get distracted very easily... you can learn more about the history behind Nullstack in [Anny's TDC talk](https://www.youtube.com/watch?v=77qeq6cSHG8). + +Initially, We just wanted to put the server code alongside the client code, because the projects We were working on had very similar patterns, and one of those patterns was that the clients would completely change their minds all the time, and your regular clean code kinda thing was not keeping up with the changes. + +I often noticed myself trying to fit into the format of the framework and changing features, or even avoiding creating new API endpoints because i didn't wanna make things to coupled or complicated. In Nullstack i just need to create a new function in the same class that just returns whatever data i need just for that case, which makes me a lot more productive and makes me think of what i'm building a lot more often than how i am building it. + +## Does it use a virtual dom or a compiler or signals? +The answer is yes. Nullstack has what I like to call a "Virtual Pipeline" it optimizes things differently in different scenarios for different environments. However that is just an implementation detail, the main thing is that it **just works** and We may change anything internal at any time. The only condition We have is that anything that works in vanilla JS should work in Nullstack, so We won't adopt any cool new trends if it limits the developer experience, or if the developer now needs to be aware of new edge cases instead of getting stuff done. + +## Does it uses Classes or Functions? +It uses whatever JavaScript code you can come up with. By default it follows the same paradigm as vanilla: functions are pure, and classes hold state. I know I will lose a lot of devs after the previous sentence, but keep in mind when people say "classes are bad" they actually mean "classes are bad on the current framework I'm using" . In Nullstack it just feels very natural, give it a try. + +## Is it blazingly fast? +Yes. But it is optimized for what I consider the "right type of fast", it's fast for the users. It uses a mix of architectures to optimize for different scenarios, but all of them aim to have the users have very responsive experiences, even when they are offline. + +You can always benchmark things and be excited about microseconds, but that all ends when your user 3g is not feeling like reaching your server that day. + +That being said, We love spending time micro benchmarking things and it's actually pretty fast, if you sneak into our commit history you will notice We went for "what We need to create products" first then We went "optimization happy", as you should if you plan to code professionally and not just watching clickbait. + + + +## What can i build with it? Does it scale? +You can build anything you can build with regular JavaScript. We've built so far plenty of PWAs, blockchain applications across multiple blockchains (dApps), mobile games, capacitor applications, electron applications, chrome extensions, and even things to visualize [brain to computer interface](https://ae.studio/brain-computer-interface) data that require a lot of performance. Currently, We have a SaaS with hundreds of thousands of hits a day, and it is holding just fine on a "regular JavaScript-priced" server. + +## How can i use a new framework? it won't have an ecosystem. +Remember when I mentioned We keep everything vanilla just working? that makes most JavaScript packages for browser and server compatible with Nullstack out of the box, that's a pretty huge ecosystem in my opinion. But also if you are feeling like a mad scientist, you could always just install your favorite framework on top of a Nullstack's application by rendering to an element controlled by it. + +## Does it have any kind of telemetry? +No, We do not collect any data. Nullstack was not built as a framework first, it was extracted from real applications We worked on over the years, so the features it has are based on what We needed as opposite of what the data would point would cause better thumbnails. + +*- But how will you guys know what features We want then?* + +You can always tell us on discord or [create an issue on GitHub](https://github.com/nullstack/nullstack/issues), We will be happy to talk about it! + +## Does Nullstack have any social media? +Of the 6 main contributors of Nullstack 6 of them are autistic, including the person writing this wall of text... so you mostly lost us at the "social" part. We did try tho, and We created a [YouTube Channel](https://www.youtube.com/nullstack), a [Twitter](https://twitter.com/nullstackapp), and an [Instagram](https://www.instagram.com/nullstackapp/), but 4 of us also have ADHD so We ended up procrastinating and not posting on it, oopsie. We are pretty active on [Discord](https://discord.gg/eDZfKz264v) though, that's the place We are forced to log in anyway to coordinate our raids. + +## What is Nulla-Chan? +Nulla-Chan is the avatar of Nullstack, it belongs to a category of avatars called a "Waifu". If you don't know what a waifu is, that probably means that you have your life on the right track. Fun fact, the waifu character was created by the author's IRL waifu. + +## What was the hardest part creating a framework? +Definitively it was deciding if We should spell it "full stack", "fullstack", or "full-stack". Seriously please tell us on discord which one to pick. + +## How can i get started? +Just go to your favorite terminal and type "npx create-nullstack-app app-name" and use the templates available through the CLI. \ No newline at end of file diff --git a/i18n/en-US/articles/full-stack-lifecycle.md b/i18n/en-US/articles/full-stack-lifecycle.md index b539a0fa..66dd2858 100644 --- a/i18n/en-US/articles/full-stack-lifecycle.md +++ b/i18n/en-US/articles/full-stack-lifecycle.md @@ -1,5 +1,5 @@ --- -title: Full-Stack Lifecycle +title: Full Stack Lifecycle description: Lifecycle methods are special named functions that you can declare in the class. --- @@ -47,6 +47,8 @@ Nullstack will wait till the promise is resolved and then finally generate the H If the user is navigating from another route this method will run in the client. +After this method promise is fulfilled `this.initiated` will be set to true + ```jsx import Nullstack from 'nullstack'; @@ -60,7 +62,12 @@ class Component extends Nullstack { }); } - // ... + render() { + if(!this.initiated) return false + return ( +{this.task.description}
+ ) + } } @@ -69,6 +76,32 @@ export default Component; > ✨ Learn more about [server functions](/server-functions). +## Launch + +Runs before pre-rendering and at each awakening. + +You can update the component with things that doesn't require data fetching operations. + +> ✨ Use this lifecycle to setup Meta tags. + +```jsx +import Nullstack from 'nullstack'; + +class Component extends Nullstack { + + // ... + + launch({ page }) { + page.title = 'Very good title that considers SEO' + } + + // ... + +} + +export default Component; +``` + ## Hydrate This method is async and will only run in the client. @@ -77,6 +110,8 @@ This method will always run no matter which environment started the component. This is a good place to trigger dependencies that manipulate the dom or can only run on the client-side. +After this method promise is fulfilled `this.hydrated` will be set to true + ```jsx import Nullstack from 'nullstack'; @@ -90,7 +125,12 @@ class Component extends Nullstack { }, 1000); } - // ... + render() { + if(!this.hydrated) return false + return ( +timer id: {this.timer}
+ ) + } } @@ -143,6 +183,8 @@ This is the place to clean up whatever you set up in the `hydrate` method. The instance will be garbage collected after the `Promise` is resolved. +After this method promise is fulfilled `this.terminated` will be set to true which is useful in the case of [persistent components](/persistent-components) + ```jsx import Nullstack from 'nullstack'; @@ -154,13 +196,15 @@ class Component extends Nullstack { clearInterval(this.timer); } + executeBackgroundTask() { + if(!this.terminated) { + // ... + } + } + // ... } export default Component; -``` - -## Next steps - -⚔ Learn about [server functions](/server-functions). \ No newline at end of file +``` \ No newline at end of file diff --git a/i18n/en-US/articles/getting-started.md b/i18n/en-US/articles/getting-started.md index ab8ba026..00102d3b 100644 --- a/i18n/en-US/articles/getting-started.md +++ b/i18n/en-US/articles/getting-started.md @@ -1,22 +1,23 @@ --- title: Getting Started -description: Create full-stack javascript applications within seconds +description: Create full stack JavaScript applications within seconds +action: ⚔ Learn [how to create a nullstack project](/getting-started). --- > 📌 You can watch a video tutorial on our [Youtube Channel](https://www.youtube.com/watch?v=l23z00GEar8&list=PL5ylYELQy1hyFbguVaShp3XujjdVXLpId). -Create full-stack javascript applications within seconds using `npx` to generate your project files from the latest template. +Create full stack JavaScript applications within seconds using `npx` to generate your project files from the latest template. -> 🔥 The minimum required [node.js](https://nodejs.org) version for development mode is *12.12.0*. - -> ⚠ If the directory you are in contains spaces, you use Windows and `npx` gives errors, read about [the known npx bug](#the-known-npx-bug). +> 🔥 The minimum required [node.js](https://nodejs.org) version for development mode is *12.20.0*. Replace `project-name` with your project name and run the command below to start a project: ```sh -npx create-nullstack-app project-name +npx create-nullstack-app@latest project-name ``` +> 💡 You can use a CLI to select the blank javascript or typescript template or select the template with tailwind css. + Change directory to the generated folder: ```sh @@ -26,42 +27,52 @@ cd project-name Install the dependencies: ```sh -npm install +npm install # or yarn ``` Start the application in development mode: ```sh -npm start +npm start # or yarn start ``` ## Understanding the generated files The following folders and files will be generated: -### index.js +### server.js + +This is the server entry and generator point. + +It is a convenient place to set up global things like [database](/how-to-use-mongodb-with-nullstack) and manipulate server `context`, details in [application startup](/application-startup). -This is the [Webpack](https://webpack.js.org) entry point. +### client.js -Usually, you don't have to touch this file, but it is a convenient place to import global dependencies like CSS frameworks. +This is the client entry and generator point. + +It is a convenient place to import global dependencies like CSS frameworks and manipulate client `context`. ### src/ This folder will contain the actual source code of your application. -### src/Application.njs +### src/Application.jsx This is your application main file. ->✨ Learn more about the [njs file extension](/njs-file-extension "Nullstack Javascript"). +>✨ Learn more about the [jsx elements](/jsx-elements "Nullstack JavaScript"). -The `start` function will be automatically called once when you run `npm start`, use it to populate your server [context](/context) with things like [database](/how-to-use-mongodb-with-nullstack), [settings](/context-settings), and [secrets](/context-secrets). +When you run `npm start` it is consumed in **server**/**client** JS files by their `Nullstack.start` function, which starts and returns both [`context`](/context), that you can use to set up things like [database](/how-to-use-mongodb-with-nullstack) using [settings](/context-settings) and [secrets](/context-secrets). >✨ Learn more about the [application startup](/application-startup). -### src/Application.scss +#### TypeScript + +You can use Nullstack with TypeScript, just rename `njs` to `nts` or `jsx` to `tsx`. -This is an empty file just to demonstrate that you can use [SCSS with Nullstack](/styles). +### src/Application.css + +This is an empty file just to demonstrate that you can use [CSS with Nullstack](/styles). It is a good practice to import a style file in a component with the same name. @@ -89,32 +100,4 @@ This is the compiled result of your application in production mode. > 🔥 Do not touch this folder ->✨ Learn more about [how to deploy a Nullstack application](/how-to-deploy-a-nullstack-application). - -## The known npx bug - -Warned on `npx` issues like [#100](https://github.com/zkat/npx/issues/100), [#110](https://github.com/zkat/npx/issues/110) and [#143](https://github.com/zkat/npx/issues/146), it has an error when trying to resolve the path to his cache folder when contains spaces. - -If this happens to you, our recommendations are: - -- Using downloaded as you normally would with `npm`: - ```sh - npm i -g create-nullstack-app - create-nullstack-app project-name - ``` - -- or, change the cache folder directory, as stated [here](https://github.com/zkat/npx/issues/146#issuecomment-384016791) and [here](https://github.com/zkat/npx/issues/146#issuecomment-384019497): - - - If you want to keep the use of space, replace `FirstName` with the one used on your path and run: - ```sh - npm config set cache "C:\Users\FirstName~1\AppData\Roaming\npm-cache" --global - ``` - - - or, using another path without spaces: - ```sh - npm config set cache C:\tmp\nodejs\npm-cache --global - ``` - -## Next step - -⚔ Create your first [renderable component](/renderable-components). \ No newline at end of file +>✨ Learn more about [how to deploy a Nullstack application](/how-to-deploy-a-nullstack-application). \ No newline at end of file diff --git a/i18n/en-US/articles/how-to-customize-webpack.md b/i18n/en-US/articles/how-to-customize-webpack.md new file mode 100644 index 00000000..0a953a4f --- /dev/null +++ b/i18n/en-US/articles/how-to-customize-webpack.md @@ -0,0 +1,58 @@ +--- +title: How to customize Webpack +description: You can create your own custom webpack config to extend Nullstacks default configs +--- + +You can create your own custom `webpack.config.js` at the projects root folder to extend Nullstacks default configs + +Nullstack exposes the file `nullstack/webpack.config.js` which exports a server and client function, each being the config for the respective environment + +You can import nullstack webpack config with the following code + +```jsx +const [server, client] = require('nullstack/webpack.config'); + +module.exports = [server, client] +``` + +You can customize a single environment by wrapping the targeted function + +```jsx +const [server, client] = require('nullstack/webpack.config'); + +const glob = require('glob'); +const PurgecssPlugin = require('purgecss-webpack-plugin'); + +function customClient(...args) { + const config = client(...args); + if (config.mode === 'production') { + config.plugins.push(new PurgecssPlugin({ + paths: glob.sync(`src/**/*`, { nodir: true }), + content: ['./**/*.njs'], + safelist: ['script', 'body', 'html', 'style'], + defaultExtractor: content => content.match(/[^<>"'`\s]*[^<>"'`\s:]/g) || [], + })); + } + + return config; +} + +module.exports = [server, customClient] +``` + +You can also extend both environments at once by creating a wrapper around both environments + +```jsx +const [server, client] = require('nullstack/webpack.config'); +const CadencePlugin = require('cadence-webpack-plugin'); + +function applyCadencePlugin(environments) { + return environments.map((environment) => (...args) => { + const config = environment(...args); + config.plugins.push(new CadencePlugin()) + return config; + }) +} + +module.exports = applyCadencePlugin([server, client]) +``` \ No newline at end of file diff --git a/i18n/en-US/articles/how-to-deploy-a-nullstack-application.md b/i18n/en-US/articles/how-to-deploy-a-nullstack-application.md index 22e01413..70212281 100644 --- a/i18n/en-US/articles/how-to-deploy-a-nullstack-application.md +++ b/i18n/en-US/articles/how-to-deploy-a-nullstack-application.md @@ -33,8 +33,8 @@ node .production/server.js After you [generate a static site](/static-site-generation), all you have to do is move the output folder to any host machine capable of serving HTML. -## Next step +## Examples -> 🎉 **Congratulations**. You are done with the advanced concepts! - -⚔ Learn [how to use MongoDB with Nullstack](/how-to-use-mongodb-with-nullstack). \ No newline at end of file +- [How to deploy to Vercel](/examples/how-to-deploy-to-vercel) +- [How to deploy to Github Pages](/examples/how-to-deploy-to-github-pages) +- [How to deploy to Heroku](/examples/how-to-deploy-to-heroku) \ No newline at end of file diff --git a/i18n/en-US/articles/instance-self.md b/i18n/en-US/articles/instance-self.md deleted file mode 100644 index bab34b0d..00000000 --- a/i18n/en-US/articles/instance-self.md +++ /dev/null @@ -1,265 +0,0 @@ ---- -title: Instance Self -description: The self object is a proxy in the Nullstack Context available in client and gives you information about the instance lifecycle ---- - -- Type: `object` -- Origin: [Nullstack Context](/context#----nullstack-context) -- Availability: **client** -- **readonly** in **client** context - -It gives you information about the instance lifecycle and it's unique [`key`](#instance-key). - -Each instance receives its own `self` object. - -The following keys are available in the object: - -- [`key`](#instance-key): `string` - -When a lifecycle method is resolved, even if not declared, an equivalent key is set to `true` in `self`. - -If the component was server-side rendered the `prerendered` key will remain `true` until it is terminated. - -The `element` key points to the DOM selector and is only guaranteed to exist when `hydrate` is being called since `prepare` and `initiate` could run in the server. - -> 💡 Do not use `element` to guess the environment, instead use the [`environment`](/context-environment) for that. - -Observing `self` is a nice way to avoid giving placeholder information to the end-user. - -```jsx -import Nullstack from 'nullstack'; - -class Page extends Nullstack { - - // ... - - async initiate() { - this.price = await this.getPrice(); - } - - async hydrate({self}) { - self.element.querySelector('input').focus(); - } - - render({self}) { - if(!self.prerendered && !self.initiated) return false; - return ( - - ) - } - -} - -export default Page; -``` - -> 💡 Components that get optimized into [functional components](/renderable-components) have no access to `self`. - -## Instance Key - -- Type: `string` -- Origin: [Component Context](/context#----component-context) -- Availability: **client** -- **readonly** in **client** context or after defined it's value as attribute - -It allows you to persist the instance when it moves in the dom. - -You can declare one `key` per instance. - -> 💡 If you do not declare a `key` nullstack will generate one based on dom depth. - -> 🔥 Keys cannot start with "_." to avoid conflicts with Nullstack generated keys - -Keys must be globally unique since the component could move anywhere around the dom and not only between its siblings. - -### Preserving state - -Keys are useful to preserve state in [stateful components](/stateful-components) when you move them in the dom. - -This is especially useful for dynamically sized lists that invoke components. - -```jsx -import Nullstack from 'nullstack'; -import Item from './Item'; - -class List extends Nullstack { - - // ... - - async initiate() { - this.items = await this.getItems(); - } - - render({self}) { - const componentKey = self.key; - return ( -Paragraph!
+ > + ) +} +``` + +Wherever it is used, the above functional component will be rendered as follows: + +```html + +Paragraph!
+``` + ## SVG Elements SVG can be used as if it were any regular HTML tag. @@ -222,6 +143,8 @@ export default Header; You can map over lists without declaring a `key`. +> ✨ A key in Nullstack is an ID for a specific component instance. Learn more about the [instance key](/instance-self#instance-key). + Lists that may change length must be wrapped in a parent element just for them. ```jsx @@ -271,8 +194,6 @@ class List extends Nullstack { export default List; ``` -> ✨ Sometimes you will notice keys in the map. Learn more about the [instance key](/instance-self#instance-key). - ## Inner HTML You can set the inner HTML of an element with the `html` attribute. @@ -304,11 +225,39 @@ export default Post; > 🔥 Be careful! When using user-generated HTML you are in risk of script injection -## The head tag +## Body tag -Renderable components can render inside the `head` tag an unlimited number of times at any depth of the application. +Renderable components can render a `body` tag an unlimited number of times at any depth of the application. + +The `body` attributes of the body tag that are rendered will be merged into the real body tag in the DOM + +```jsx +import Nullstack from 'nullstack'; + +class Application extends Nullstack { + + // ... + + render() { + return ( + + {this.modalOpen && + +Hello {name}
+} +``` + +```jsx +// src/Application.jsx +import HelloDweeb from './HelloDweeb'; + +export default function Application({ name }) { + return ( +Hello {name} welcome to {project.name}
+} +``` + +```jsx +// src/Application.tsx +import HelloProject from './HelloProject'; + +export default function Application() { + return ( +Hi i'm {params.name}
+ ) + } + + // routes can have dynamic segments + render() { + return ( +texto
"; + return ( +texto
texto
texto
{context.count}
+{context.count}
+Parágrafo!
+ > + ) +} +``` + +Onde quer que seja usado, o componente funcional acima será renderizado da seguinte forma: + +```html + +Parágrafo!
+``` ## Elementos SVG @@ -306,7 +330,7 @@ export default Post; ## A tag `head` -Componentes renderizáveis podem renderizar dentro da tag `head` um número ilimitado de vezes em qualquer profundidade do aplicativo. +Componentes sem estado podem renderizar dentro da tag `head` um número ilimitado de vezes em qualquer profundidade do aplicativo. A tag `head` só será atualizada durante o processo de [renderização no servidor](/pt-br/renderizacao-no-servidor) e mudanças serão ignorados após o processo de [hidratação](/pt-br/ciclo-de-vida-full-stack). diff --git a/i18n/pt-BR/articles/contexto-data.md b/i18n/pt-BR/articles/contexto-data.md index 8e66edec..fc44b49e 100644 --- a/i18n/pt-BR/articles/contexto-data.md +++ b/i18n/pt-BR/articles/contexto-data.md @@ -59,4 +59,4 @@ export default ContextData ## Próxima Etapa -⚔ Aprenda sobre a [chave `environment` do contexto](/pt-br/contexto-environment). \ No newline at end of file +⚔ Aprenda sobre a [chave `instances` do contexto](/pt-br/contexto-instances). \ No newline at end of file diff --git a/i18n/pt-BR/articles/contexto-instances.md b/i18n/pt-BR/articles/contexto-instances.md new file mode 100644 index 00000000..ae4ab7ce --- /dev/null +++ b/i18n/pt-BR/articles/contexto-instances.md @@ -0,0 +1,93 @@ +--- +title: Contexto Instances +description: O objeto instances é um proxy no Contexto Nullstack disponível no client e fornece todas as instâncias ativas da aplicação +--- + +- Tipo: `object` +- Origem: [Contexto Nullstack](/pt-br/contexto#----contexto-nullstack) +- Disponibilidade: **client** +- **readwrite** no contexto do **client** + +Fornece todas as instâncias ativas da aplicação. + +> 💡 Instâncias ativas são as criadas e ainda não [terminadas](/pt-br/ciclo-de-vida-full-stack#terminate) + +Conforme explicado em [`key` da instância](/pt-br/instancia-self#key-da-inst-ncia), keys desempenham um grande papel na definição de um identificador único para componentes. + +> 🔥 Nullstack confia que seus desenvolvedores sabem o que estão fazendo e expõe o máximo de comportamentos internos possíveis para o programador usar como quiser, use com precaução. + +Adicionando uma `key` única ao **Counter** torna-o disponível na lista `instances`. + +```jsx +import Nullstack from 'nullstack'; +import Counter from './Counter'; +import AnyOtherComponent from './AnyOtherComponent'; + +class Application extends Nullstack { + + render() { + return ( +Contador: {this.value}
+ } + +} + +export default Counter; +``` + +Você pode acessar qualquer método e variável de instância da instância **counter** em **AnyOtherComponent** + +```jsx +import Nullstack from 'nullstack'; + +class AnyOtherComponent extends Nullstack { + + render({ instances }) { + return ( + + ) + } + +} + +export default AnyOtherComponent; +``` + +O uso de `instances` libera possibilidades ilimitadas de novos comportamentos como: + +- Um ícone de notificação na navbar que pode ser atualizado de outros componentes em certas ações +- Um componente de *toast* que pode ser invocado de qualquer lugar de sua aplicação +- Um sistema de *store* com ações customizadas similares ao Redux +- Algo que nós nem imaginamos, sonhe criativamente e poste suas ideias no GitHub! + +## Próxima Etapa + +⚔ Aprenda sobre a [chave `environment` do contexto](/pt-br/contexto-environment). \ No newline at end of file diff --git a/i18n/pt-BR/articles/contexto-page.md b/i18n/pt-BR/articles/contexto-page.md index d5225303..316b5621 100644 --- a/i18n/pt-BR/articles/contexto-page.md +++ b/i18n/pt-BR/articles/contexto-page.md @@ -131,8 +131,4 @@ class Application extends Nullstack { export default Application; ``` -> 🔥 A atribuição à chave `status` durante o modo [aplicativo de página única](/pt-br/ciclo-de-vida-full-stack) não terá efeito. - -## Próximo Passo - -⚔ Aprenda sobre a [chave `project` do contexto](/pt-br/contexto-project). \ No newline at end of file +> 🔥 A atribuição à chave `status` durante o modo [aplicativo de página única](/pt-br/ciclo-de-vida-full-stack) não terá efeito. \ No newline at end of file diff --git a/i18n/pt-BR/articles/contexto-project.md b/i18n/pt-BR/articles/contexto-project.md index 74054304..b595e196 100644 --- a/i18n/pt-BR/articles/contexto-project.md +++ b/i18n/pt-BR/articles/contexto-project.md @@ -13,18 +13,16 @@ Ele te dá informações sobre o manifest do app e algumas metatags. As chaves de `project` serão usadas para gerar metatags durante a renderização do lado do servidor e devem ser definidas antes que [`initiate`](/pt-br/ciclo-de-vida-full-stack) seja resolvido. -As chaves de `project` serão usadas para gerar o **manifest** do app e devem ser definidas durante a [inicialização da aplicação](/pt-br/inicializacao-da-aplicacao). +As chaves de `project` serão usadas para gerar o **manifest** do app. -A chave `disallow` será usada para gerar o **robots.txt** e deverá ser definida durante a [inicialização da aplicação](/pt-br/inicializacao-da-aplicacao). +A chave `disallow` será usada para gerar o **robots.txt**. -As chaves de `project` serão congeladas após a [inicialização da aplicação](/pt-br/inicializacao-da-aplicacao). +As chaves a seguir estão disponíveis no objeto e são suportadas como variáveis de ambiente da seguinte maneira: -As chaves a seguir estão disponíveis no objeto: - -- **domain**: `string` -- **name**: `string` -- **shortName**: `string` -- **color**: `string` +- **domain**: `string` (`NULLSTACK_PROJECT_DOMAIN`) +- **name**: `string` (`NULLSTACK_PROJECT_NAME`) +- **shortName**: `string` (`NULLSTACK_PROJECT_SHORT_NAME`) +- **color**: `string` (`NULLSTACK_PROJECT_COLOR`) - **backgroundColor**: `string` - **type**: `string` - **display**: `string` @@ -35,13 +33,15 @@ As chaves a seguir estão disponíveis no objeto: - **favicon**: `string` (url relativo ou absoluto) - **disallow**: `array` de `string` (caminhos relativos) - **sitemap**: `boolean` ou `string` (url relativo ou absoluto) -- **cdn**: `string` (url absoluto) -- **protocol**: `string` (http or https) +- **cdn**: `string` (`NULLSTACK_PROJECT_CDN`) +- **protocol**: `string` (`NULLSTACK_PROJECT_PROTOCOL`) Além de `domain`, `name` and `color` todas as outras chaves tem padrões sensíveis gerados com base no escopo do aplicativo. Se você não declarar a chave `icons`, Nullstack irá escanear quaisquer ícones com o nome seguindo o padrão "icon-[LARGURA]x[ALTURA].png" na sua pasta **public**. +A meta tag `apple-touch-icon` de `head` irá ser igual ao seu arquivo `icon-180x180.png`. + Se a chave `sitemap` estiver definida como `true` o seu arquivo **robots.txt** irá apontar o sitemap para `https://${project.domain}/sitemap.xml`. A chave `cdn` irá prefixar seu pacote de assets e ficará disponível no contexto para que você possa manualmente prefixar outros ativos. @@ -49,32 +49,46 @@ A chave `cdn` irá prefixar seu pacote de assets e ficará disponível no contex A chave `protocol` é "http" no modo de desenvolvimento e "https" e no modo produção por predefinição. ```jsx +// server.js import Nullstack from 'nullstack'; +import Application from './src/Application'; + +const context = Nullstack.start(Application); + +context.start = function() { + const { project } = context; + project.name = 'Nullstack'; + project.shortName = 'Nullstack'; + project.domain = 'nullstack.app'; + project.color = '#d22365'; + project.backgroundColor = '#d22365'; + project.type = 'website'; + project.display = 'standalone'; + project.orientation = 'portrait'; + project.scope = '/'; + project.root = '/'; + project.icons = { + '72': '/icon-72x72.png', + '128': '/icon-128x128.png', + '512': '/icon-512x512.png' + }; + project.favicon = '/favicon.png'; + project.disallow = ['/admin']; + project.sitemap = true; + project.cdn = 'cdn.nullstack.app'; + project.protocol = 'https'; +} -class Application extends Nullstack { +export default context; +``` - static async start({project}) { - project.name = 'Nullstack'; - project.shortName = 'Nullstack'; - project.domain = 'nullstack.app'; - project.color = '#d22365'; - project.backgroundColor = '#d22365'; - project.type = 'website'; - project.display = 'standalone'; - project.orientation = 'portrait'; - project.scope = '/'; - project.root = '/'; - project.icons = { - '72': '/icon-72x72.png', - '128': '/icon-128x128.png', - '512': '/icon-512x512.png' - }; - project.favicon = '/favicon.png'; - project.disallow = ['/admin']; - project.sitemap = true; - project.cdn = 'cdn.nullstack.app'; - project.protocol = 'https'; - } +> Mais sobre o `context.start` em [inicialização da aplicação](/pt-br/inicializacao-da-aplicacao). + +```jsx +// src/Application.njs +import Nullstack from 'nullstack'; + +class Application extends Nullstack { prepare({project, page}) { page.title = project.name; @@ -85,8 +99,4 @@ class Application extends Nullstack { export default Application; ``` -> 💡 Você pode substituir o **manifest.json** gerado automaticamente e **robots.txt** inserindo o seu próprio arquivo na pasta **public** - -## Próximo Passo - -⚔ Aprenda sobre a [chave `settings` do contexto](/pt-br/contexto-settings). \ No newline at end of file +> 💡 Você pode substituir o **manifest.json** gerado automaticamente e **robots.txt** inserindo o seu próprio arquivo na pasta **public** \ No newline at end of file diff --git a/i18n/pt-BR/articles/contexto-secrets.md b/i18n/pt-BR/articles/contexto-secrets.md index 8cf0b543..e9cf0cf5 100644 --- a/i18n/pt-BR/articles/contexto-secrets.md +++ b/i18n/pt-BR/articles/contexto-secrets.md @@ -10,31 +10,32 @@ description: O objeto secrets é um proxy no Contexto Nullstack disponível no s Você pode usá-lo para configurar dados sensíveis para sua aplicação. -Chaves de `secrets` são congeladas depois da [inicialização da aplicação](/pt-br/inicializacao-da-aplicacao). +Você pode atribuir qualquer chave com qualquer tipo ao objeto. -As seguintes chaves estão disponíveis no objeto: +Você pode atribuir chaves a `secrets` dinamicamente com base no ambiente atual usando [`context.environment`](/pt-br/contexto-environment). -- **development**: `object` -- **production**: `object` -- **[qualquerSegredo]**: `any` +```jsx +// server.js +import Nullstack from 'nullstack'; +import Application from './src/Application'; -Você pode definir chaves diferentes para as chaves `development` e `production`, obtendo assim valores diferentes para cada [ambiente](/pt-br/contexto-environment). +const context = Nullstack.start(Application); -Caso uma chave seja definida diretamente no objeto `secrets` ela ficará disponível para ambos os ambientes. +context.start = function() { + const { secrets, environment } = context; + secrets.endpoint = 'https://domain.com/api'; + secrets.privateKey = environment.development ? 'DEV_API_KEY' : 'PROD_API_KEY'; +} -A leitura das chaves deve ser feita diretamente do objeto `secrets`, pois o Nullstack vai retornar o valor referido de acordo com o [ambiente](/pt-br/contexto-environment). +export default context; +``` ```jsx +// src/Application.njs import Nullstack from 'nullstack'; class Application extends Nullstack { - static async start({secrets}) { - secrets.development.privateKey = 'SANDBOX_API_KEY'; - secrets.production.privateKey = 'PRODUCTION_API_KEY'; - secrets.endpoint = 'https://domain.com/api'; - } - static async fetchFromApi({secrets}) { const response = await fetch(secrets.endpoint, { headers: { @@ -49,10 +50,6 @@ class Application extends Nullstack { export default Application; ``` -Qualquer chave de ambiente iniciada por NULLSTACK_SECRETS_ será mapeada para o *secrets* de seu respectivo ambiente. - -> 🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY será mapeada para `secrets.privateKey` - -## Próximo passo +Qualquer variável de ambiente iniciada por NULLSTACK_SECRETS_ será mapeada para o `secrets` de seu respectivo ambiente. -⚔ Aprendendo sobre o [`self` da instância](/pt-br/instancia-self). +> 🐱💻 NULLSTACK_SECRETS_PRIVATE_KEY será mapeada para `secrets.privateKey` \ No newline at end of file diff --git a/i18n/pt-BR/articles/contexto-settings.md b/i18n/pt-BR/articles/contexto-settings.md index b3439992..69be4073 100644 --- a/i18n/pt-BR/articles/contexto-settings.md +++ b/i18n/pt-BR/articles/contexto-settings.md @@ -11,31 +11,32 @@ description: O objeto settings é um proxy no Contexto Nullstack disponível em Você pode usá-lo para configurar seu aplicativo com informações públicas. -Chaves de `settings` serão congeladas após a [inicialização do aplicativo](/pt-br/inicializacao-da-aplicacao). +Você pode atribuir qualquer chave com qualquer tipo ao objeto. -As chaves a seguir estão disponíveis no objeto: +Você pode atribuir chaves a `settings` dinamicamente com base no ambiente atual usando [`context.environment`](/pt-br/contexto-environment). -- **development**: `object` -- **production**: `object` -- **[anySetting]**: `any` +```jsx +// server.js +import Nullstack from 'nullstack'; +import Application from './src/Application'; -Você pode declarar as chaves para as chaves `development` ou `production` para ter diferentes configurações por [ambiente](/pt-br/contexto-environment). +const context = Nullstack.start(Application); -Se você declarar uma chave diretamente para o objeto `settings` ela ficará disponível em ambos os ambientes. +context.start = function() { + const { settings, environment } = context; + settings.endpoint = 'https://domain.com/api'; + settings.privateKey = environment.development ? 'DEV_API_KEY' : 'PROD_API_KEY'; +} -Quando lendo de uma chave você deve ler diretamente do objeto `settings` e o Nullstack retornará o valor mais adequado para aquele [ambiente](/pt-br/contexto-environment). +export default context; +``` ```jsx +// src/Application.njs import Nullstack from 'nullstack'; class Application extends Nullstack { - static async start({settings}) { - settings.development.publicKey = 'SANDBOX_API_KEY'; - settings.production.publicKey = 'PRODUCTION_API_KEY'; - settings.endpoint = 'https://domain.com/api'; - } - async hydrate({settings}) { const response = await fetch(settings.endpoint, { headers: { @@ -50,11 +51,6 @@ class Application extends Nullstack { export default Application; ``` +Qualquer variável de ambiente começando com NULLSTACK_SETTINGS_ será mapeado para o `settings` daquele ambiente. -Qualquer chave de ambiente começando com NULLSTACK_SETTINGS_ será mapeado para as confirgurações daquele ambiente. - -> 🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY será mapeado para `settings.publicKey` - -## Próximo passo - -⚔ Aprenda sobre a [chave `secrets` do contexto](/pt-br/contexto-secrets). +> 🐱💻 NULLSTACK_SETTINGS_PUBLIC_KEY será mapeado para `settings.publicKey` \ No newline at end of file diff --git a/i18n/pt-BR/articles/contexto.md b/i18n/pt-BR/articles/contexto.md index e879064a..e139dbc0 100644 --- a/i18n/pt-BR/articles/contexto.md +++ b/i18n/pt-BR/articles/contexto.md @@ -34,10 +34,9 @@ Essas são as informações que o framework disponibiliza para você por padrão - [`response`](/pt-br/requisicao-e-resposta-do-servidor#requisi--o-e-resposta) - [`secrets`](/pt-br/contexto-secrets) -### As chaves de instância do cliente são: +### A chave disponível apenas no cliente: -- [`self`](/pt-br/instancia-self) -- [`children`](/pt-br/componentes-renderizaveis#componentes-com-filhos) +- [`instances`](/pt-br/contexto-instances) ## 2 - Contexto Aplicação @@ -45,7 +44,7 @@ Quando você define uma chave para o contexto, ela fica disponível para desestr Atualizar uma chave no contexto faz com que a aplicação seja renderizada novamente automaticamente. -Você pode pensar nisso como um único conceito para substituir **stores**, **contexts**, **services**, e **reducers** ao mesmo tempo, usando o padrão de injeção de dependência com objetos javascript padrão. +Você pode pensar nisso como um único conceito para substituir **stores**, **contexts**, **services**, e **reducers** ao mesmo tempo, usando o padrão de injeção de dependência com objetos JavaScript padrão. ```jsx import Nullstack from 'nullstack'; @@ -82,7 +81,7 @@ import Counter from './Counter'; class Application extends Nullstack { - static async start(context) { + prepare(context) { context.totalCount = 0; } @@ -101,7 +100,11 @@ export default Application; ## 3 - Contexto Componente -Este contém os atributos que você declara em sua tag, incluindo os [`data`](/pt-br/contexto-data). +Este contém os atributos que você declara em sua tag, e incluindo: + +- [`data`](/pt-br/contexto-data) +- [`self`](/pt-br/instancia-self) +- [`children`](/pt-br/componentes-renderizaveis#componentes-com-filhos) Se o atributo é declarado em uma tag componente cada função desse componente terá acesso a esse atributo em seu contexto. @@ -180,8 +183,4 @@ class Counter extends Nullstack { } export default Counter; -``` - -## Próximo passo - -⚔ Aprenda sobre [Rotas e Parâmetros](/pt-br/rotas-e-parametros). \ No newline at end of file +``` \ No newline at end of file diff --git a/i18n/pt-BR/articles/estilos.md b/i18n/pt-BR/articles/estilos.md index 12d1dc22..185814e1 100644 --- a/i18n/pt-BR/articles/estilos.md +++ b/i18n/pt-BR/articles/estilos.md @@ -20,10 +20,58 @@ class Header extends Nullstack { export default Header; ``` -No modo de produção, o Nullstack usa [PurgeCSS](https://purgecss.com), que limpa seu arquivo **client.css**, mas tem alguns truques. +## Classes e estilos condicionais -> ✨ Saiba mais sobre [fazendo uma safelist do seu css](https://purgecss.com/safelisting.html) +Você pode passar valores falsy para `style` e `class` para pular a renderização de condicionais. -## Próximo passo +```jsx +import Nullstack from 'nullstack'; + +class Counter extends Nullstack { + + count = 0; + + render() { + return ( +Olá, eu sou a {params.name}
+ ) + } + + // as rotas podem ter segmentos dinâmicos + render() { + return ( + <> ++ {description} +
++ {" "} + {this.i18n.tagline} +
+ +{tagline.text}
+{tagline.text}
} -{this.i18n.tagline}
- -{this.i18n.tagline}
+ +
- {this.i18n.githubCacheWarning}
+{this.i18n.githubCacheWarning}
) } - + render() { - if(!this.i18n) return false; + if (!this.i18n) return false; return ( -{description}
-{this.i18n.tagline}
-+ {description} +
+ + ); + } + + render() { + if (!this.i18n) return false; + return ( ++ {this.i18n.tagline} +
+ +