提交 8c5209ef 编写于 作者: L Luis Fernando Alvarez D 提交者: Tim Neutkens

Update typescript examples (#7867)

* Updated with-jest-typescript

* Updated the mobx-state-tree-typescript example

* Removed the sitemap with typescript example

* Updated the with css typings example
上级 24fa6b35
{
"env": {
"development": {
"presets": [
"next/babel",
"@zeit/next-typescript/babel"
]
},
"production": {
"presets": [
"next/babel",
"@zeit/next-typescript/babel"
]
},
"test": {
"presets": [
[
"next/babel",
{
"preset-env": {
"modules": "commonjs"
}
}
],
"@zeit/next-typescript/babel"
]
}
}
"presets": ["next/babel"]
}
/// <reference types="next" />
/// <reference types="next/types/global" />
const withTypescript = require('@zeit/next-typescript')
module.exports = withTypescript()
......@@ -14,10 +14,8 @@
},
"devDependencies": {
"@types/jest": "^24.0.11",
"@types/next": "^8.0.1",
"@types/react": "^16.8.8",
"@types/react-dom": "^16.8.2",
"@zeit/next-typescript": "^1.1.1",
"babel-core": "^6.26.3",
"babel-jest": "^24.5.0",
"enzyme": "^3.9.0",
......
import CarsOverview from './../src/modules/cars/Overview'
import CarsOverview from '../src/modules/cars/Overview'
const CarsPage = () => <CarsOverview />
......
import Login from './../src/modules/auth/Login'
import Login from '../src/modules/auth/Login'
const LoginPage = () => <Login />
......
......@@ -3,7 +3,7 @@ import * as React from 'react'
import * as T from './types'
export interface CarsOverviewProps {
cars: T.CarList
cars?: T.CarList
}
export interface CarsOverviewState {
......@@ -26,7 +26,7 @@ export default class CarsOverview extends React.Component<
this.setState({ selectedCar: car })
}
renderCarsList = (cars: T.CarList): JSX.Element => {
renderCarsList = (cars?: T.CarList): JSX.Element => {
if (!cars || cars.length === 0) {
return <p>No cars</p>
}
......
......@@ -14,8 +14,20 @@
"sourceMap": true,
"skipLibCheck": true,
"baseUrl": ".",
"typeRoots": ["./node_modules/@types"],
"lib": ["dom", "es2015", "es2016"]
"typeRoots": [
"./node_modules/@types"
],
"lib": [
"dom",
"es2015",
"es2016"
],
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"resolveJsonModule": true,
"isolatedModules": true
},
"exclude": [
"node_modules",
......@@ -23,5 +35,10 @@
"**/*.spec.tsx",
"**/*.test.ts",
"**/*.test.tsx"
],
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx"
]
}
{
"presets": [
"next/babel",
"@zeit/next-typescript/babel"
],
"plugins": [
["@babel/plugin-proposal-decorators", { "legacy": true }]
]
"presets": ["next/babel"],
"plugins": [["@babel/plugin-proposal-decorators", { "legacy": true }]]
}
/// <reference types="next" />
/// <reference types="next/types/global" />
const withTypescript = require('@zeit/next-typescript')
module.exports = withTypescript()
......@@ -4,11 +4,9 @@
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start",
"tslint": "tslint -c tslint.json -p tsconfig.json"
"start": "next start"
},
"dependencies": {
"@zeit/next-typescript": "1.1.0",
"mobx": "^5.9.0",
"mobx-react": "^5.4.3",
"mobx-state-tree": "^3.11.0",
......@@ -18,13 +16,8 @@
"typescript": "^3.0.1"
},
"devDependencies": {
"@types/next": "^6.1.4",
"@types/react": "^16.4.12",
"@babel/plugin-proposal-decorators": "^7.3.0",
"tslint": "^5.9.1",
"tslint-config-standard": "^7.0.0",
"tslint-loader": "^3.5.3",
"tslint-react": "^3.4.0"
"@types/react": "^16.4.12"
},
"license": "ISC"
}
......@@ -41,10 +41,10 @@ export type IStoreSnapshotOut = SnapshotOut<typeof Store>
export const initializeStore = (isServer, snapshot = null) => {
if (isServer) {
store = Store.create({ foo: 6, lastUpdate: Date.now() })
store = Store.create({ foo: 6, lastUpdate: Date.now(), light: false })
}
if ((store as any) === null) {
store = Store.create({ foo: 6, lastUpdate: Date.now() })
store = Store.create({ foo: 6, lastUpdate: Date.now(), light: false })
}
if (snapshot) {
applySnapshot(store, snapshot)
......
{
"compileOnSave": false,
"compilerOptions": {
"experimentalDecorators": true,
"target": "esnext",
"module": "esnext",
"jsx": "preserve",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictNullChecks": true,
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true,
"skipLibCheck": true,
"baseUrl": ".",
"typeRoots": ["./node_modules/@types"],
"lib": ["dom", "es2015", "es2016"]
}
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"experimentalDecorators": true
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}
{
"extends": ["tslint-config-standard", "tslint:latest", "tslint-react"],
"rules": {
"indent": [true, "spaces"],
"jsx-no-lambda": false,
"jsx-no-multiline-js": false,
"max-line-length": false,
"no-console": false,
"no-object-literal-type-assertion": false,
"no-submodule-imports": [true, "next"],
"no-unused-variable": false,
"space-before-function-paren": false,
"ter-indent": [true, 2],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-preblock",
"check-rest-spread",
"check-separator",
"check-typecast",
"check-type-operator"
]
}
}
{
"presets": [
"next/babel",
"@zeit/next-typescript/babel"
]
}
*~
*.swp
tmp/
npm-debug.log
.DS_Store
.build/*
.next
.vscode/
node_modules/
.coverage
.env
.next
yarn-error.log
\ No newline at end of file
.build/
.next/
.vscode/
node_modules/
README.md
.env
.eslintrc.js
.gitignore
\ No newline at end of file
# Example with sitemap.xml and robots.txt using Express server and typescript
## How to use
### Using `create-next-app`
Execute [`create-next-app`](https://github.com/segmentio/create-next-app) with [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) or [npx](https://github.com/zkat/npx#readme) to bootstrap the example:
```bash
npx create-next-app --example with-sitemap-and-robots-express-server-typescript with-sitemap-and-robots-express-server-typescript-app
# or
yarn create next-app --example with-sitemap-and-robots-express-server-typescript with-sitemap-and-robots-express-server-typescript-app
```
### Download manually
Download the example:
```bash
curl https://codeload.github.com/zeit/next.js/tar.gz/canary | tar -xz --strip=2 next.js-canary/examples/with-sitemap-and-robots-expres-server-typescript
cd with-sitemap-and-robots-express-server-typescript
```
Install it and run:
```bash
npm install
npm run dev
# or
yarn
yarn dev
```
Deploy it to the cloud with [now](https://zeit.co/now) ([download](https://zeit.co/download))
```bash
now
```
## The idea behind the example
This example app shows you how to set up sitemap.xml and robots.txt files for proper indexing by search engine bots.
The app is deployed at: https://sitemap-robots.now.sh. Open the page and click the links to see sitemap.xml and robots.txt. Here is a snapshot of these files, with sitemap.xml on the left and robots.txt on the right:
![sitemap-robots](https://user-images.githubusercontent.com/26158226/38786210-4d0c3f70-40db-11e8-8e44-b2c90cfd1b74.png)
Notes:
- routes `/a` and `/b` are added to sitemap manually
- routes that start with `/posts` are added automatically to sitemap; in a real application, you will get post slugs from a database
When you start this example locally:
- your app with run at https://localhost:8000
- sitemap.xml will be located at http://localhost:8000/sitemap.xml
- robots.txt will be located at http://localhost:8000/robots.txt
In case you want to deploy this example, replace the URL in the following locations with your own domain:
- `hostname` in `src/server/sitemap.ts`
- `ROOT_URL` in `src/server/app.ts`
- `Sitemap` at the bottom of `src/server/robots.txt`
- `alias` in `now.json`
Deploy with `now` or with `yarn now` if you specified `alias` in `now.json`
## Typescript notes
express.js and next.js require slighty different forms of javascript (es5 vs. es6, es6 modules vs commonjs modules, that sort of thing) so there are two tsconfig files that are used to generate the appropriate _.js and _.jsx files in dist from the _.ts and _.tsx files in src (`tsconfig.next.json` and `tsconfig.server.json`). Any files under /src/server are assumed to be for express, any other files under /src are assumed to be for next. To keep things simple the two typescript transpiles using these two config files are run directly from npm commands in package.json so all you need to run the example are simple commands like
`npm run start`
or
`npm run dev`
This example has most of the hot module reload plumbing setup for both express- and next-related source files when you use `npm run dev` but it's currently only watching the _.js and _.jsx files in /dist for changes. You will need to manually `npm run build-ts` in another window to transpile your modified typescript files in `src` into the watched javascript files in `dist` (it should be possible to have tsc watch the src folder and auto compile on save but that isn't wired up yet in this example). This example does also have tslint support though `npm run tslint`.
{
"env": {
"NODE_ENV": "production"
},
"scale": {
"sfo1": {
"min": 1,
"max": 1
}
},
"alias": "https://sitemap-robots-typescript.now.sh"
}
{
"name": "with-sitemap-and-robots-express-server-typescript",
"version": "1.0.0",
"license": "MIT",
"scripts": {
"build-ts": "tsc -p tsconfig.next.json && tsc -p tsconfig.express.json",
"build-static": "npx copyfiles -u 1 \"src/static/**/*\" dist",
"build-next": "next build ./dist",
"build": "npm run build-ts && npm run build-static && npm run build-next",
"start-node": "cd ./dist && node server/app.js",
"start-nodemon": "cd ./dist && nodemon server/app.js --watch server",
"start": "npm run build-ts && npm run build-static && npm run start-node",
"dev": "npm run build-ts && npm run build-static && npm run start-nodemon",
"now": "npm run build && now ./dist && now alias",
"tslint": "tslint -c tslint.json -p tsconfig.next.json && tslint -c tslint.json -p tsconfig.server.json"
},
"dependencies": {
"express": "^4.16.3",
"next": "latest",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"sitemap": "^1.13.0"
},
"devDependencies": {
"@types/express": "^4.16.0",
"@zeit/next-typescript": "1.1.0",
"nodemon": "^1.14.11",
"tslint": "^5.9.1",
"tslint-config-standard": "^7.0.0",
"tslint-loader": "^3.5.3",
"tslint-react": "^3.4.0",
"typescript": "^3.0.1"
}
}
const RobotsLink = () => {
return (
<a href="/robots.txt" target="_blank">
Robots
</a>
)
}
export { RobotsLink }
const SitemapLink = () => {
return (
<a href="/sitemap.xml" target="_blank">
Sitemap
</a>
)
}
export { SitemapLink }
import Head from 'next/head'
import React from 'react'
import { RobotsLink } from '../components/RobotsLink'
import { SitemapLink } from '../components/SitemapLink'
function Index() {
return (
<div style={{ padding: '10px 45px' }}>
<Head>
<title>Index page</title>
<meta name="description" content="description for indexing bots" />
</Head>
<p>
<RobotsLink />
<br />
<SitemapLink />
</p>
</div>
)
}
export default Index
User-agent: *
Allow: /a
Allow: /b
Allow: /posts/*
Disallow: /
Disallow: /a/*
Disallow: /b/*
Disallow: /posts
Sitemap: https://sitemap-robots.now.sh/sitemap.xml
\ No newline at end of file
import * as express from 'express'
import * as next from 'next'
import { addSitemap } from './sitemap'
const dev = process.env.NODE_ENV !== 'production'
const port = process.env.PORT || 8000
const ROOT_URL = dev
? `http://localhost:${port}`
: 'https://sitemap-robots-typescript.now.sh'
const app = next({ dev })
const handle = app.getRequestHandler()
// Nextjs's server prepared
app.prepare().then(() => {
const server = express()
addSitemap({ server })
server.get('*', (req, res) => {
handle(req, res)
})
// starting express server
server.listen(port, err => {
if (err) {
throw err
}
console.log(`> Ready on ${ROOT_URL}`)
})
})
interface IPost {
name: string
slug: string
}
const posts = () => {
const arrayOfPosts: IPost[] = []
const n = 5
for (let i = 1; i < n + 1; i += 1) {
arrayOfPosts.push({ name: `Post ${i}`, slug: `post-${i}` })
}
return arrayOfPosts
}
export { IPost, posts }
import * as path from 'path'
import * as sm from 'sitemap'
import { posts } from './posts'
const sitemap = sm.createSitemap({
cacheTime: 600000, // 600 sec - cache purge period
hostname: 'https://sitemap-robots-typescript.now.sh'
})
const addSitemap = ({ server }) => {
const Posts = posts()
for (const post of Posts) {
sitemap.add({
changefreq: 'daily',
priority: 0.9,
url: `/posts/${post.slug}`
})
}
sitemap.add({
changefreq: 'daily',
priority: 1,
url: '/a'
})
sitemap.add({
changefreq: 'daily',
priority: 1,
url: '/b'
})
// Note {} in next line is a placeholder filling the spot where the req parameter
// would normally be listed (but isn't listed here since we aren't using it)
server.get('/sitemap.xml', ({}, res) => {
sitemap.toXML((err, xml) => {
if (err) {
res.status(500).end()
return
}
res.header('Content-Type', 'application/xml')
res.send(xml)
})
})
}
export { addSitemap }
{
"compileOnSave": true,
"compilerOptions": {
"pretty": true,
"experimentalDecorators": true,
"target": "es5",
"module": "commonjs",
"jsx": "preserve",
"allowJs": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictNullChecks": true,
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true,
"skipLibCheck": true,
"typeRoots": ["./node_modules/@types"],
"outDir": "./dist/server",
"lib": ["dom", "es2015", "es2016"]
},
"include": ["./src/server/**/*"]
}
{
"compileOnSave": true,
"compilerOptions": {
"pretty": true,
"experimentalDecorators": true,
"target": "esnext",
"module": "es6",
"jsx": "preserve",
"allowJs": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strictNullChecks": true,
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true,
"skipLibCheck": true,
"typeRoots": ["./node_modules/@types"],
"outDir": "./dist",
"lib": ["dom", "es2015", "es2016"]
},
"include": ["./src/**/*"],
"exclude": ["./src/server/**/*"]
}
{
"extends": ["tslint-config-standard", "tslint:latest", "tslint-react"],
"rules": {
"indent": [true, "spaces"],
"jsx-no-lambda": false,
"jsx-no-multiline-js": false,
"max-line-length": false,
"no-console": false,
"no-object-literal-type-assertion": false,
"no-submodule-imports": [true, "next"],
"no-unused-variable": false,
"space-before-function-paren": false,
"ter-indent": [true, 2],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
}
],
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-preblock",
"check-rest-spread",
"check-separator",
"check-typecast",
"check-type-operator"
]
}
}
{
"presets": [
"next/babel",
"@zeit/next-typescript/babel"
]
}
\ No newline at end of file
......@@ -39,4 +39,4 @@ now
## The idea behind the example
This example shows how to generate type declarations for using CSS modules with TypeScript. It uses the [next-css](https://github.com/zeit/next-plugins/tree/master/packages/next-css) and [next-typescript](https://github.com/zeit/next-plugins/tree/master/packages/next-typescript) plugins with [typings-for-css-modules-loader](https://www.npmjs.com/package/typings-for-css-modules-loader). With additional samples of how to apply using sass, less and stylus.
This example shows how to generate type declarations for using CSS modules with TypeScript. It uses the [next-css](https://github.com/zeit/next-plugins/tree/master/packages/next-css) plugin and [typings-for-css-modules-loader](https://www.npmjs.com/package/typings-for-css-modules-loader). With additional samples of how to apply using sass, less and stylus.
/// <reference types="next" />
/// <reference types="next/types/global" />
const withCSS = require('@zeit/next-css')
const withTypescript = require('@zeit/next-typescript')
/* With additional configuration on top of CSS Modules */
module.exports = withTypescript(
withCSS({
cssModules: true,
cssLoaderOptions: {
camelCase: true,
namedExport: true
},
webpack (config, options) {
if (!options.isServer) {
/* Using next-css */
for (let entry of options.defaultLoaders.css) {
if (entry.loader === 'css-loader') {
entry.loader = 'typings-for-css-modules-loader'
break
}
module.exports = withCSS({
cssModules: true,
cssLoaderOptions: {
camelCase: true,
namedExport: true
},
webpack (config, options) {
if (!options.isServer) {
/* Using next-css */
for (let entry of options.defaultLoaders.css) {
if (entry.loader === 'css-loader') {
entry.loader = 'typings-for-css-modules-loader'
break
}
}
/* Using next-less */
/*
/* Using next-less */
/*
for (let entry of options.defaultLoaders.less) {
if (entry.loader === 'css-loader') {
entry.loader = 'typings-for-css-modules-loader';
......@@ -29,8 +27,8 @@ module.exports = withTypescript(
}
*/
/* Using next-sass */
/*
/* Using next-sass */
/*
for (let entry of options.defaultLoaders.sass) {
if (entry.loader === 'css-loader') {
entry.loader = 'typings-for-css-modules-loader';
......@@ -39,8 +37,8 @@ module.exports = withTypescript(
}
*/
/* Using next-stylus */
/*
/* Using next-stylus */
/*
for (let entry of options.defaultLoaders.stylus) {
if (entry.loader === 'css-loader') {
entry.loader = 'typings-for-css-modules-loader';
......@@ -48,9 +46,8 @@ module.exports = withTypescript(
}
}
*/
}
return config
}
})
)
return config
}
})
......@@ -10,14 +10,12 @@
},
"dependencies": {
"@zeit/next-css": "^1.0.1",
"@zeit/next-typescript": "^1.1.1",
"next": "latest",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"typings-for-css-modules-loader": "^1.7.0"
},
"devDependencies": {
"@types/next": "7.0.2",
"@types/react": "16.4.16",
"@types/react-dom": "16.0.9",
"typescript": "3.1.3"
......
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"allowJs": true,
"alwaysStrict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": ["dom", "es2017"],
"module": "esnext",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"removeComments": false,
"preserveConstEnums": true,
"sourceMap": true
}
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"target": "esnext"
},
"exclude": ["node_modules"],
"include": ["**/*.ts", "**/*.tsx"]
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册