create-dan
Version:
Dan frameworks
437 lines (324 loc) • 8.57 kB
Markdown
# project-name
project-description
## Requirement
### Software
- Node 8+ (Recommanded Node 12)
- Npm 6+
- Widows 10 / Mac 10.14
### Knowledge
- [Js Es 2020](https://tc39.es/ecma262/)
- [React](https://reactjs.org/)
- [Next](https://nextjs.org/)
- [Sass](https://sass-lang.com/)
## Installation
`npm i`
## Commands
- `npm run dev` : Run the server in development mode
- `npm run build` : Build the server for the production
- `npm start` : Start the production server, be sure to have build before
## Project folders
- `/src` Dynamic files (js, scss, html) compiled with webpack
- `/src/config/*` Configurations file
- `/public` Static files like images & fonts
- `/public/locales/{locale}/` Folders where json and static images will be localized
- `/server` Server tools
- `/.next` Build & cache folder
## Configuration
Configurations files are located in `/src/config/*` :
- `config.js` : JS Configation for client & server.
Client side :
```js
import getConfig from 'config'
const config = getConfig()
```
Server side :
```js
const config = require('./src/config')()
```
Javascript configuration can be override with the `/.env` file or with `environements variables`.
Priority order is :
1) config.js
2) environements variables
3) .env
- `config.scss` : Sass configuration
```css
@import "~config/styles.scss";
```
Only use mixins & variables in `config.scss`.
## Sass & CSS modules
- Sass : [https://sass-lang.com/](https://sass-lang.com/)
- CSS modules : [https://github.com/css-modules/css-modules](https://github.com/css-modules/css-modules)
## Basic Auth
You can add a `BasicAuth` for your staging. Just add a `AUTH_LOGIN` and `AUTH_PASSWORD` in `.env`.
```apache
# Authentification
AUTH_LOGIN = login
AUTH_PASSWORD = password
```
> BasicAuth don't work in `export` mode. Add a `.htpasswd` if you are host by an apache server.
## DAN's Pakages
### Router
#### Setup localized routes
Setup your supported locales in the `/.env` file.
```apache
# Supported locales (default in first)
LOCALES = en, fr
```
#### Routes
Add your routes in `/src/routes.js` with :
- `addI18nRoute(path, file, name)` Add a new route for all locales.
```js
/*
Add a new route named "home" for the page "/src/pages/index.js".
Supported URLs are :
- /my-page
- /:locale/my-page
*/
addI18nRoute('/my-page', 'index', 'home')
```
- `addRoute(path, file, name)` Add a new route without localisation.
```js
/*
Add a new route named "home" for the page "/src/pages/index.js".
Supported URLs are :
- /my-page
*/
addRoute('/my-page', 'index', 'home')
```
#### Link & pushRoute
|Method / Component|Description|
|-|-|
|`<Link route="routeName" params={params} options={}>...</Link>`|React component for bind a link|
|`pushRoute(routeName, [params], [option])`|Javascript function for push a new route in the router|
Use `<Link>` For add a link in react with `dan/router` :
```js
import { Link } from 'dan/router'
export default () => (
<Link route="home" params={{ foo: 'bar' }}>
<a>Back to home<a>
</Link>
)
```
You can override localized routes with the parameter `locale`. Be sure to have setup i18n context in your page (see in the section `i18n`).
```js
<Link route="home" params={{ locale: 'fr' }}>
<a>Page d'accueil</a>
</Link>
```
It's also possible to call `pushRoute(route, params, options)` for javascript link.
```js
import { pushRoute } from 'dan/router'
export default () => (
<span onClick={() => pushRoute('home', { foo: 'bar' })}>
Back to home
</span>
)
```
### i18n
With the i18n package you can have :
- localized URL
- localized pages
`i18n` is a React context in `/src/dan/i18n.js`. You can import it with :
```js
import { I18nContext } from 'dan/i18n'
```
#### API
|Method / Component|Description|
|-|-|
|`i18n.locale`|Get the current locale|
|`i18n.localize(key, [params], [options])`|Get a localized text|
|`<Localize {...params} {...options}>key</Localize>`|React component for localize a text|
#### Setup Provider
For add the provider in a page, call `pageWithI18n(MyPage)`, it will also inject `i18n` in React properties.
```jsx
import { pageWithI18n } from 'dan/i18n'
function HomePage({ i18n }) {
return (
<div>
Current locale : {i18n.locale}
</div>
)
}
export default pageWithI18n(HomePage)
```
#### Consumer
You can now use the context in a component of this page with `withI18n(MyComponent)` or `useI18n()`.
```jsx
import { withI18n } from 'dan/i18n'
function MyComponent({ i18n }) {
return (
<div>
Current locale : {i18n.locale}
</div>
)
}
export default withI18n(MyComponent)
```
Or you can also get the i18n context with `useI18n()`
```jsx
import { useI18n } from 'dan/i18n'
export default () => {
const i18n = useI18n()
return (
<div>
Current locale : {i18n.locale}
</div>
)
}
```
#### Localized JSON
You can use static localized texts with JSON files. They are located in `/public/locales/{locale}/*.json`
```json
{
"hello": "Hello {name} !"
}
```
By dedault `main.json` is loaded. For add more JSON in a page :
```js
export default pageWithI18n(MyPage, [
'main', // /public/locales/{locale}/main.js
'items' // /public/locales/{locale}/items.json
])
```
Get localized text with :
- `localize(key, params, options)`
- `<Localize {...params} {...options}>key</Localize>`
```js
import { localize, Localize } from 'dan/i18n'
export default () => (
<div>
{localize('hello', { name: 'dan' })}
<Localize name="dan">hello</Localize>
</div>
)
```
### Is
`is` is the pakage for get information about the current user. It works with useragent.
`is` is a React context in `/src/dan/is.js`. You can import it with :
```js
import { IsContext } from 'dan/is'
```
#### API
|Property|Description|
|-|-|
|`is.ie`|Internet explorer 11|
|`is.edge`|Edge|
|`is.firefox`|Firefox|
|`is.chrome`|Chrome|
|`is.safari`|Safari|
|`is.ios`|iOs|
|`is.android`|Android|
|`is.tablet`|Tablet|
|`is.mobile`|Mobile|
|`is.desktop`|Desktop|
|`is.images`|Supported images|
#### Setup Provider
For add the provider in a page, call `pageWithIs(MyPage)`, it will also inject `is` in React properties.
```jsx
import { pageWithIs } from 'dan/is'
function HomePage({ is }) {
return (
<div>
Is mobile : {is.mobile}
</div>
)
}
export default pageWithIs(HomePage)
```
#### Consumer
You can now use the context in a component of this page with `withIs(MyComponent)` or `useIs()`.
```jsx
import { withIs } from 'dan/is'
function MyComponent({ is }) {
return (
<div>
Is mobile : {is.mobile}
</div>
)
}
export default withIs(MyComponent)
```
Or you can also get the `is` context with `useIs()`
```jsx
import { useIs } from 'dan/is'
export default () => {
const is = useIs()
return (
<div>
Is mobile : {is.mobile}
</div>
)
}
```
### Assets
```js
import { newQueue } from 'dan/assets'
const q = newQueue()
q.add('data/test01.txt', { id: 'text' })
q.add('data/test02.png', { id: 'image' })
q.add('data/test02.json', { id: 'json' })
q.onComplete.once((assets) => {
console.log('Queue completed:', assets)
console.log('Text:', q.get('text'))
})
```
#### Cache
```js
import { newQueue, getFromCache } from 'dan/assets'
const q = newQueue({
cache: true // All the queue will be cached
})
q.add('data/test01.txt', {
id: 'text',
cache: true // Only this asset wil be cached
})
q.onComplete.once(() => {
console.log(getFromCache('text'))
})
```
#### Assynchronous Start
```js
import { newQueue } from 'dan/assets'
const q = newQueue({
autoStart: false
})
q.add('data/test01.mp4')
q.add('data/test02.mp4')
q.add('data/test03.mp4')
// Wait 1s before starting the queue
setTimeout(() => {
q.start()
}, 1000)
```
#### Stop & resume
```js
q.add('data/test01.mp4').catch(() => {
q.stop() // Stop
setTimeout(() => {
q.start() // Resume
}, 1000)
})
```
#### Number of simultaneous download in parallel
```js
const q = newQueue({
simultaneous: 4 // 4 simultaneous max
})
```
#### Priority
```js
const q = newQueue({
simultaneous: 2
})
q.add('data/test01.text')
q.add('data/test02.text', { priority: 1 })
q.add('data/test03.text', { priority: 2 })
q.add('data/test04.text')
// Download order will be: test02, test03, test01, test04
```
### Request animation frame
```js
import { addRaf } from 'dan/raf'
addRaf((dt) => {
console.log(`delta time: ${dt}ms`)
})