• Stars
    star
    106
  • Rank 325,871 (Top 7 %)
  • Language
    JavaScript
  • License
    Apache License 2.0
  • Created almost 7 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Next.js + Antd + MobX + Typescript starter kit

nextjs-starter-kit

Next.js + Antd + MobX + react-intl + Typescript starter kit.

Table of Contents

  1. Step1: Create an empty Next.js project
  2. Step2: Ant Design
  3. Step3: MobX
  4. Step4: React Intl
  5. Step5: TypeScript

Step1: Create an empty Next.js project

Create an empty npm project,

npm init

Fill in some information then we get a package.json file:

{
  "name": "nextjs-starter-kit",
  "version": "1.0.0",
  "description": "Next.js starter kit",
  "author": "[email protected]",
  "license": "Apache-2.0",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/soulmachine/nextjs-starter-kit.git"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}

Install Next.js,

npm install next react react-dom --save

and add a script to your package.json like this:

{
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  }
}

Finally we get a complete package.json file:

{
  "name": "nextjs-starter-kit",
  "version": "1.0.0",
  "description": "Next.js starter kit",
  "author": "[email protected]",
  "license": "Apache-2.0",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/soulmachine/nextjs-starter-kit.git"
  },
  "scripts": {
    "dev": "next",
    "build": "next build",
    "start": "next start"
  },
  "dependencies": {
    "next": "^5.0.0",
    "react": "^16.2.0",
    "react-dom": "^16.2.0"
  }
}

Create a file ./pages/index.js inside your project:

export default () => <div>Welcome to next.js!</div>

and then just run npm run dev and go to http://localhost:3000.

Step2: Ant Design

There are two hight quality React UI libaries, ant-design and material-ui, I choose ant-design because:

2.1 Install antd

npm install antd --save

2.2 Use modularized antd

Install the Babel plugin babel-plugin-import,

npm install babel-plugin-import --save-dev

Enable it in .babelrc, the .babelrc file is copied from the official example, next.js/examples/with-ant-design/.babelrc

{
  "presets": ["next/babel"],
  "plugins": [
    ["import", { "libraryName": "antd", "style": false }]
  ]
}

2.3 Import Antd CSS

Note that although we've enabled the plugin, but we pass false to the plugin's config to tell it to skip all CSS from antd, instead we'll load antd's css from CDN. This ugly solution is due to the issue that Next.js can only import CSS using styled-jsx or CSS-in-JS built in with jsx syntax and Next.js is not able to use css-loader. See the warning from official page https://github.com/zeit/next.js/#customizing-webpack-config:

Warning: Adding loaders to support new file types (css, less, svg, etc.) is not recommended because only the client code gets bundled via webpack and thus it won't work on the initial server rendering. Babel plugins are a good alternative because they're applied consistently between server/client rendering

Also see this issue Work with antd? · Issue #484 and this Importing CSS files? · Issue #544.

Create a file ./components/Layout.js in the project root directory with the following code:

import Head from 'next/head'
import { LocaleProvider } from 'antd'
import enUS from 'antd/lib/locale-provider/en_US'

export default ({ title, children }) =>
  <div>
    <Head>
      <title>{ title }</title>
      <meta name='viewport' content='width=device-width, initial-scale=1' />
      <meta charSet='utf-8' />
      <link rel='stylesheet' href='//cdnjs.cloudflare.com/ajax/libs/antd/3.2.0/antd.min.css' />
    </Head>
    <style jsx global>{`
      body {
      }
    `}</style>
    <LocaleProvider locale={enUS}>
      <div>{children}</div>
    </LocaleProvider>
  </div>

Make sure the version number is the same as antd package.json.

Copy ./pages/index.js from the official example to ./pages/antd.js(remove LocaleProvider from it), and add a link to ./pages/index.js:

import React from 'react'
import Link from 'next/link'

export default () => <div>
  <p>Welcome to next.js!</p>
  <Link href='/antd'><a>Ant Design</a></Link>
</div>

run npm run dev and go to http://localhost:3000.

Step3: MobX

See the official example examples/with-mobx-state-tree.

3.1 Install mobx, mobx-react and mobx-state-tree

npm install mobx mobx-react mobx-state-tree --save

3.2 Decorator support

Decorator support is activated by the Babel plugin babel-plugin-transform-decorators-legacy,

npm install babel-plugin-transform-decorators-legacy --save-dev

Add this plugin to .babelrc:

{
  "presets": ["next/babel"],
  "plugins": [
    "transform-decorators-legacy",
    ["import", { "libraryName": "antd", "style": false }]
  ]
}

3.3 server.js

From mobx-react's official document here, Server Side Rendering with useStaticRendering:

When using server side rendering, normal lifecycle hooks of React components are not fired, as the components are rendered only once. Since components are never unmounted, observer components would in this case leak memory when being rendered server side. To avoid leaking memory, call useStaticRendering(true) when using server side rendering. This makes sure the component won't try to react to any future data changes.

We need to customize server.js for Next.js:

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'

const { createServer } = require('http')
const { parse } = require('url')
const next = require('next')
const mobxReact = require('mobx-react')
const app = next({ dev })
const handle = app.getRequestHandler()

mobxReact.useStaticRendering(true)

app.prepare().then(() => {
  createServer((req, res) => {
    const parsedUrl = parse(req.url, true)
    handle(req, res, parsedUrl)
  }).listen(port, err => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
})

And we need to update commands in scripts:

  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "NODE_ENV=production node server.js"
  },

3.4 ClockStore

Create a file ./stores/ClockStore.js:

import { types, applySnapshot } from "mobx-state-tree"

const ClockStore = types
  .model({
    lastUpdate: types.Date,
    light: types.boolean,
  })
  .actions((self) => {
    let timer;
    function start() {
      timer = setInterval(() => {
        // mobx-state-tree doesn't allow anonymous callbacks changing data
        // pass off to another action instead
        self.update();
      })
    }

    function update() {
      self.lastUpdate = Date.now()
      self.light = true
    }

    function stop() {
      clearInterval(timer);
    }

    return { start, stop, update }
  })

let clockStore = null

export default function initClockStore(isServer, snapshot = null) {
  if (isServer) {
    clockStore = ClockStore.create({ lastUpdate: Date.now(), light: false })
  }
  if (clockStore == null) {
    clockStore = ClockStore.create({ lastUpdate: Date.now(), light: false  })
  }
  if (snapshot) {
    applySnapshot(clockStore, snapshot)
  }
  return clockStore
}

The trick here for supporting universal mobx is to separate the cases for the client and the server. When we are on the server we want to create a new store every time, otherwise different users data will be mixed up. If we are in the client we want to use always the same store. That's what we accomplish on ClockStore.js.

3.5 ClockPage

Now let's add a new page for Clock.

First create a stateless Component in ./components/Clock.js, just copy examples/with-mobx-state-tree/components/Clock.js.

Second, create a container for Clock in ./containers/Clock.js:

import React from 'react'
import { inject, observer } from 'mobx-react'
import Clock from '../components/Clock'

@inject('clock') @observer
class ClockContainer extends React.Component {
  componentDidMount() {
    this.props.clock.start()
  }

  componentWillUnmount() {
    this.props.clock.stop()
  }

  render() {
    return (
      <Clock lastUpdate={this.props.clock.lastUpdate} light={this.props.clock.light} />
    )
  }
}

export default ClockContainer

Third, create a new page ./pages/clock.js:

import React from 'react'
import Link from 'next/link'
import { Provider } from 'mobx-react'
import { getSnapshot } from 'mobx-state-tree'
import initClockStore from '../stores/ClockStore'
import Clock from '../containers/Clock'

class ClockPage extends React.Component {
  static getInitialProps({ req }) {
    const isServer = !!req
    const clockStore = initClockStore(isServer)
    return { initialState: getSnapshot(clockStore), isServer }
  }

  constructor(props) {
    super(props)
    this.clockStore = initClockStore(props.isServer, props.initialState)
  }

  render() {
    return (
      <Provider clock = {this.clockStore}>
        <div>
          <h1>Clock</h1>
          <Clock />
        </div>
      </Provider>
    )
  }
}

export default ClockPage

In every page that wants to use MobX, we need to wrap it in <Provider>, and initialize its store by calling initClockStore() in getInitialProps() and constructor.

Run npm run dev and go to http://localhost:3000/clock.

Step4: React Intl

Internationalization is a must have for most Apps, we're going to use react-intl to internationalize this App.

4.1 Install packages

npm install react-intl intl babel-plugin-react-intl accepts glob --save

4.2 server.js

On the server side we need to support server-side language negotiation, see the following code:

// Polyfill Node with `Intl` that has data for all locales.
// See: https://formatjs.io/guides/runtime-environments/#server
const IntlPolyfill = require('intl')
Intl.NumberFormat = IntlPolyfill.NumberFormat
Intl.DateTimeFormat = IntlPolyfill.DateTimeFormat

const {readFileSync} = require('fs')
const {basename} = require('path')
const {createServer} = require('http')
const { parse } = require('url')
const accepts = require('accepts')
const glob = require('glob')
const next = require('next')
const mobxReact = require('mobx-react')
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({dev})
const handle = app.getRequestHandler()

mobxReact.useStaticRendering(true)

// Get the supported languages by looking for translations in the `lang/` dir.
const languages = glob.sync('./lang/*.json').map((f) => basename(f, '.json'))

// We need to expose React Intl's locale data on the request for the user's
// locale. This function will also cache the scripts by lang in memory.
const localeDataCache = new Map()
const getLocaleDataScript = (locale) => {
  const lang = locale.split('-')[0]
  if (!localeDataCache.has(lang)) {
    const localeDataFile = require.resolve(`react-intl/locale-data/${lang}`)
    const localeDataScript = readFileSync(localeDataFile, 'utf8')
    localeDataCache.set(lang, localeDataScript)
  }
  return localeDataCache.get(lang)
}

// We need to load and expose the translations on the request for the user's
// locale. These will only be used in production, in dev the `defaultMessage` in
// each message description in the source code will be used.
const getMessages = (locale) => {
  return require(`./lang/${locale}.json`)
}

app.prepare().then(() => {
  createServer((req, res) => {
    const parsedUrl = parse(req.url, true)
    const accept = accepts(req)
    let locale = accept.language(languages)
    locale = locale || 'en'
    req.locale = locale
    req.localeDataScript = getLocaleDataScript(locale)
    req.messages = getMessages(locale)
    handle(req, res, parsedUrl)
  }).listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
})

4.3 _document.js

We need to inject the script localeDataScript() from react-intl to every page, so ./pages/_document.js comes to help:

import Document, {Head, Main, NextScript} from 'next/document'

// The document (which is SSR-only) needs to be customized to expose the locale
// data for the user's locale for React Intl to work in the browser.
export default class IntlDocument extends Document {
  static async getInitialProps (context) {
    const props = await super.getInitialProps(context)
    const {req: {locale, localeDataScript}} = context
    return {
      ...props,
      locale,
      localeDataScript
    }
  }

  render () {
    // Polyfill Intl API for older browsers
    const polyfill = `https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.${this.props.locale}`

    return (
      <html>
        <Head />
        <body>
          <Main />
          <script src={polyfill} />
          <script
            dangerouslySetInnerHTML={{
              __html: this.props.localeDataScript
            }}
          />
          <NextScript />
        </body>
      </html>
    )
  }
}

4.4 PageWithIntl HOC

import React, {Component} from 'react'
import {IntlProvider, addLocaleData, injectIntl} from 'react-intl'

// Register React Intl's locale data for the user's locale in the browser. This
// locale data was added to the page by `pages/_document.js`. This only happens
// once, on initial page load in the browser.
if (typeof window !== 'undefined' && window.ReactIntlLocaleData) {
  Object.keys(window.ReactIntlLocaleData).forEach((lang) => {
    addLocaleData(window.ReactIntlLocaleData[lang])
  })
}

export default (Page) => {
  const IntlPage = injectIntl(Page)

  return class PageWithIntl extends Component {
    static async getInitialProps (context) {
      let props
      if (typeof Page.getInitialProps === 'function') {
        props = await Page.getInitialProps(context)
      }

      // Get the `locale` and `messages` from the request object on the server.
      // In the browser, use the same values that the server serialized.
      const {req} = context
      const {locale, messages} = req || window.__NEXT_DATA__.props

      // Always update the current time on page load/transition because the
      // <IntlProvider> will be a new instance even with pushState routing.
      const now = Date.now()

      return {...props, locale, messages, now}
    }

    render () {
      const {locale, messages, now, ...props} = this.props
      return (
        <IntlProvider locale={locale} messages={messages} initialNow={now}>
          <IntlPage {...props} />
        </IntlProvider>
      )
    }
  }
}

4.5 Create a testing page

Let's create a testing page ./pages/react-intl.js:

import React, {Component} from 'react'
import Head from 'next/head'
import {FormattedMessage, FormattedNumber, defineMessages, FormattedRelative} from 'react-intl'
import pageWithIntl from '../components/PageWithIntl'
import Layout from '../components/Layout'

const {description} = defineMessages({
  description: {
    id: 'description',
    defaultMessage: 'An example app integrating React Intl with Next.js'
  }
})

class ReactIntlPage extends Component {
  static async getInitialProps ({req}) {
    return {someDate: Date.now()}
  }

  render () {
    return (
      <Layout title="React Intl">
        <Head>
          <meta name='description' content={this.props.intl.formatMessage(description)} />
        </Head>
        <p>
          <FormattedMessage id='greeting' defaultMessage='Hello, World!' />
        </p>
        <p>
          <FormattedNumber value={1000} />
        </p>
        <p>
          <FormattedRelative
            value={this.props.someDate}
            updateInterval={1000}
          />
        </p>
      </Layout>
    )
  }
}

export default pageWithIntl(ReactIntlPage)

4.6 Messages files

Create a directory ./lang, put messages files here.

./lang/en.json:

{
  "description": "An example app integrating React Intl with Next.js",
  "greeting": "Hello, World!"
}

./lang/fr.json:

{
  "description": "Un exemple d'application intégrant React Intl avec Next.js",
  "greeting": "Bonjour le monde!"
}

./lang/zh.json:

{
  "description": "一个将React Intl 与 Next.js 集成的例子",
  "greeting": "你好,世界!"
}

Run npm run dev and go to http://localhost:3000/clock.

4.7 babel-plugin-react-intl

babel-plugin-react-intl is a plugin that extracts string messages for translation from modules that use React Intl. To make it work we need to configure it.

First enable it in .babelrc:

{
  "presets": ["next/babel"],
  "plugins": [
    "transform-decorators-legacy",
    ["import", { "libraryName": "antd", "style": false }],
    ["react-intl", {
        "messagesDir": "./lang/.messages/"
    }]
  ]
}

"messagesDir": "lang/.messages/" means this will output a .json file corresponding to each component from which React Intl messages were extracted.

Add lang/.messages/ to the file .gitignore.

Then we write a script to merge all files under "lang/.messages/" to a single json file ./lang/en.json:

const {readFileSync, writeFileSync} = require('fs')
const {resolve} = require('path')
const glob = require('glob')

const defaultMessages = glob.sync('./lang/.messages/**/*.json')
  .map((filename) => readFileSync(filename, 'utf8'))
  .map((file) => JSON.parse(file))
  .reduce((messages, descriptors) => {
    descriptors.forEach(({id, defaultMessage}) => {
      if (messages.hasOwnProperty(id)) {
        throw new Error(`Duplicate message id: ${id}`)
      }
      messages[id] = defaultMessage
    })
    return messages
  }, {})

writeFileSync('./lang/en.json', JSON.stringify(defaultMessages, null, 2))
console.log(`> Wrote default messages to: "${resolve('./lang/en.json')}"`)

And add this script to the build command in package.json:

"build": "next build && node ./scripts/default-lang.js",

Run npm run build and you will see it generates a file ./lang/en.json.

4.8 Antd LocaleProvider

This step is optional unless we want internationalize Antd's builtin strings.

In server.js we load :

const antdLocaleCache = new Map()
const rootToLang = {
  'ar': 'ar_EG',
  'bg': 'bg_BG',
  'ca': 'ca_ES',
  'cs': 'cs_CZ',
  'de': 'de_DE',
  'el': 'el_GR',
  'en': 'en_US',
  'es': 'es_ES',
  'et': 'et_EE',
  'fa': 'fa_IR',
  'fi': 'fi_FI',
  'fr': 'fr_FR',
  'is': 'is_IS',
  'it': 'it_IT',
  'ja': 'ja_JP',
  'ko': 'ko_KR',
  'nb': 'nb_NO',
  'nl': 'nl_NL',
  'pl': 'pl_PL',
  'pt': 'pt_PT',
  'ru': 'ru_RU',
  'sk': 'sk_SK',
  'sr': 'sr_RS',
  'sv': 'sv_SE',
  'th': 'th_TH',
  'tr': 'tr_TR',
  'uk': 'uk_UA',
  'vi': 'vi_VN',
  'zh': 'zh_CN'
}
const getAntdLocaleData = (locale) => {
  const root = locale.split('-')[0]
  const lang = rootToLang[root]
  if (!antdLocaleCache.has(lang)) {
    const localeData = require(`antd/lib/locale-provider/${lang}`)
    antdLocaleCache.set(lang, localeData)
  }
  return antdLocaleCache.get(lang)
}

And we need to wrap PageWithIntl.js with Antd LocaleProvider:

diff --git a/step4/components/PageWithIntl.js b/step4/components/PageWithIntl.js
index 1bcf0af..cd45005 100644
--- a/step4/components/PageWithIntl.js
+++ b/step4/components/PageWithIntl.js
@@ -1,5 +1,6 @@
 import React, {Component} from 'react'
 import {IntlProvider, addLocaleData, injectIntl} from 'react-intl'
+import LocaleProvider from 'antd/lib/locale-provider';
 
 // Register React Intl's locale data for the user's locale in the browser. This
 // locale data was added to the page by `pages/_document.js`. This only happens
@@ -23,21 +24,23 @@ export default (Page) => {
       // Get the `locale` and `messages` from the request object on the server.
       // In the browser, use the same values that the server serialized.
       const {req} = context
-      const {locale, messages} = req || window.__NEXT_DATA__.props
+      const {locale, messages, antdLocale} = req || window.__NEXT_DATA__.props
 
       // Always update the current time on page load/transition because the
       // <IntlProvider> will be a new instance even with pushState routing.
       const now = Date.now()
 
-      return {...props, locale, messages, now}
+      return {...props, locale, messages, antdLocale, now}
     }
 
     render () {
-      const {locale, messages, now, ...props} = this.props
+      const {locale, messages, antdLocale, now, ...props} = this.props
       return (
-        <IntlProvider locale={locale} messages={messages} initialNow={now}>
-          <IntlPage {...props} />
-        </IntlProvider>
+        <LocaleProvider locale={ antdLocale }>
+          <IntlProvider locale={locale} messages={messages} initialNow={now}>
+            <IntlPage {...props} />
+          </IntlProvider>
+        </LocaleProvider>
       )
     }
   }

Step5: TypeScript

5.1 Install TypeScript compiler

First install the TypeScript compiler and the plugin for Next.js,

npm install @zeit/next-typescript typescript --save-dev

5.2 Install TypeScript type definitions for libraries

Install all dependented librarys' typings so that vscode can have better code completion for these libraries,

npm install --save-dev @types/next @types/react @types/react-dom @types/react-intl @types/styled-jsx

We don't need to install typings for antd, mobx, react-mobx and mobx-state-tree because they have built-in TypeScript support, i.e., they have their own type definitions.

5.3 Configure TypeScript

5.3.1 tsconfig.json

Create a new file tsconfig.json, and the content of tsconfig.json is as the following:

{
  "compileOnSave": false,
  "compilerOptions": {
    "strict": true,
    "target": "esnext",
    "module": "esnext",
    "jsx": "preserve",
    "allowJs": true,
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "experimentalDecorators": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "removeComments": false,
    "preserveConstEnums": true,
    "sourceMap": true,
    "skipLibCheck": true,
    "baseUrl": ".",
    "typeRoots": [
      "./node_modules/@types/",
      "./src/@types/"
    ],
    "lib": [
      "dom",
      "es2015",
      "es2016"
    ]
  },
  "include": [
    "src/**/*"
  ]
}

In the config above, please pay attention to a few things:

  • Use "jsx": "preserve" instead of react-native because Next.js supports .jsx file extension after version 5.0.0, previously it only recogonize .js files.
  • @types/ directory must be inside ./src, otherwise Typescript won't compile .d.ts files in @types/

5.3.2 next.config.js

const withTypescript = require('@zeit/next-typescript')
module.exports = withTypescript({
  webpack(config, options) {
    return config
  }
})

5.3.3 server.js

By default the pages directory is located at the project's root directory, since in this project we move pages to src, we need to tell Next.js where to find pages directory:

const app = next({dev, dir: 'src'})

5.3.4 package.json

Also we need to tell the next build command the location of pages directory in package.json:

  "scripts": {
    "dev": "node server.js",
    "build": "next build ./src && node ./scripts/default-lang.js",
    "start": "NODE_ENV=production node server.js"
  }

5.3.5 Setting a custom build directory

By default next build will output files to src/.next, which is not clean, I need to move the .next folder out of src.

And we need to tell Next.js to change the output directory to ../build, by default it is src/.next within the same folder that the pages folder resides in. Set distDir in next.config.js:

const withTypescript = require('@zeit/next-typescript')
module.exports = withTypescript({
  webpack(config, options) {
    return config
  },
  distDir: '../build'
})

Basically the build process is: ./src -> next build-->./build, then server.js will read files from ./build and run as a server.

5.4 Rewrite all code in Typescript

  • Move ./pages/ files to src/
  • Move ./components/ files to src/
  • Move ./containers/ files to src/
  • Rename all ./src/**/*.js files to .tsx files, and rewrite them in Typescript
  • Rename ./stores/ClockStore.js to ./stores/ClockStore.ts

Add a file @types/styled-jsx.d.ts, to make vscode recognize styled-jsx syntax,

import 'react'
// Augmentation of React
declare module 'react' {
  interface StyleHTMLAttributes<T> extends React.HTMLAttributes<T> {
    jsx?: boolean;
    global?: boolean;
  }
}

Please read the source code for all details.

5.5 TSLint

5.5.1 Install TSLint

npm install tslint --save-dev

5.5.2 tslint.json

Configure tslint in tslint.json,

{
  "extends": ["tslint:latest"],
  "rules": {
    "semicolon": [true, "never"],
    "interface-name": [true, "never-prefix"],
    "no-submodule-imports": false,
    "no-object-literal-type-assertion": false
  }
}

5.5.3 package.json

Add a command to scripts in package.json,

"lint": "tslint \"src/**/*.{ts,tsx}\"",

Now you can run npm run lint to lint your source code.

5.6 prettier

Prettier is a very popular code formatter for Javascript, Typescript and many other frontend languages, first install it,

npm install prettier --save-dev

Add a prettier command to "scripts" section in package.json and remove --fix option of tslint:

"lint": "tslint \"src/**/*.{ts,tsx}\"",
"prettier": "find ./src -type f | xargs prettier --write"

The --write option will modify files in place, so we don't need tslint to fix files.

Configure prettier with prettier.config.js file:

module.exports = {
  semi: false,
};

Modify tslint.json to make its rules not conflict with prettier:

{
  "extends": ["tslint:latest"],
  "rules": {
    "arrow-parens": false,
    "interface-name": [true, "never-prefix"],
    "no-object-literal-type-assertion": false,
    "no-submodule-imports": false,
    "semicolon": [true, "never"],
    "trailing-comma": [true, {"multiline": "nerver", "singleline": "never"}]
  }
}

Use pre-commit to run prettier and tslint before commit,

  • Install pre-commit by running npm install pre-commit --save-dev
  • Add a pre-commit section to package.json: "pre-commit": ["prettier", "lint"],

References

More Repositories

1

leetcode

LeetCode题解,151道题完整版。广告:推荐刷题网站 https://www.lintcode.com/?utm_source=soulmachine
TeX
11,033
star
2

machine-learning-cheat-sheet

Classical equations and diagrams in machine learning
TeX
5,853
star
3

acm-cheat-sheet

Acm Cheat Sheet
TeX
1,691
star
4

system-design

系统设计面试题精选
1,289
star
5

algorithm-essentials

算法精粹--举一反三,抛弃题海战术
JavaScript
775
star
6

search-engine-principle

搜索引擎原理详解,开源电子书
202
star
7

crypto-notebooks

Jupyter notebooks for analyzing crypto data
Jupyter Notebook
96
star
8

hackerrank

HackerRank题解
31
star
9

vue-tutorial

Learn Vue.js step by step 一步一步学习Vue.js
JavaScript
31
star
10

awesome-blockchain-whitepapers

Awesome blockchain white papers
HTML
30
star
11

docker-images

My daily used docker images
Dockerfile
25
star
12

scala-cheat-sheet

Scala cheat sheet
TeX
23
star
13

react-starter-kits

Build a react starter kit step by step
JavaScript
17
star
14

spark-example-project

A Spark WordCount example as a standalone SBT project
Scala
16
star
15

weixinqunzhushou

微信群助手机器人
Python
15
star
16

coin-wallets

One library to manage all cryptocurrencies.
TypeScript
12
star
17

ubuntu-provision

Ubuntu 一键装机
Vim Script
11
star
18

ts-cli-starter

TypeScript CLI project template.
Dockerfile
10
star
19

meteor-tutorial

Meteor+React+Antd tutorial step by step
JavaScript
10
star
20

awesome-deep-trading

Papers of deep learning for trading
9
star
21

JythonExample

A simple Jython example to execute Python scripts from Java
Java
8
star
22

effective-spark

7
star
23

cn-blog

我的中文技术博客
CSS
6
star
24

delimited-protobuf

A read/write library for length-delimited protobuf messages
Python
4
star
25

virtual-machines

My daily virtual machine images
Shell
4
star
26

stock-crawler

Crawl US stocks daily OHLCV data
Jupyter Notebook
4
star
27

with-react-intl

Rewrite with-react-intl/ in Typescript
TypeScript
3
star
28

soulmachine.github.io

My tech blog
HTML
3
star
29

GasPrice

Retrieve ETH gas price from gasnow.org per 15s.
Python
3
star
30

machinelearning

some code snippets about machinelearning
Java
3
star
31

algorithms

some algorithm code snippets
JavaScript
3
star
32

subredditstats

Scrape subredditstats.com everyday.
Python
3
star
33

algorithm-essentials-java

3
star
34

eos-endpoint

Retrieve a list of valid EOS API endpoints
TypeScript
2
star
35

weibo-friends

A toy spark program
Scala
2
star
36

eidos-miner

EIDOS miner, 1000 times faster than your phone
JavaScript
2
star
37

MNIST

Python
2
star
38

soulmachine

Automatically exported from code.google.com/p/soulmachine
C
2
star
39

crowdcrawler

Crawling Data with Crowdsourcing
2
star
40

crypto-crawler-workflow

Crawl websocket data from cryptocurrency exchanges using Sogou workflow
2
star
41

JRubyExample

A simple JRuby example to execute Ruby scripts from Java
Java
1
star
42

JparsecExample

A Jparsec calculator example
Java
1
star
43

coin-kline

Get real-time Kline data from cryptocurrency exchanges.
JavaScript
1
star
44

ts-node-starter

Typescript CLI project based on ts-node
TypeScript
1
star
45

projecteuler

ProjectEuler题解
1
star
46

DevOps

我的Linux开发环境和工具
1
star
47

node-cli-starter

Node.js CLI project template
Dockerfile
1
star
48

vue-demos

a collection of simple demos of Vue.js
HTML
1
star
49

coinmarketcap-node

A complete Node.js library for CoinmarketCap.
TypeScript
1
star
50

nas-papers-comparison

NAS Papers Comparison
1
star
51

crypto-notebooks1

Jupyter notebooks for analyzing crypto data
Jupyter Notebook
1
star
52

crypto-subreddit

Get number of subscribers for cryptocurrency subreddits
Python
1
star
53

okex-withdrawal-fee

Get OKEx withdrawal fees of all currencies.
TypeScript
1
star
54

alien-invasion-simulator

Go
1
star
55

crypto-orderbook

In-memory level2 order book.
Rust
1
star
56

scalding-example-project

A Scalding WordCountJob example as a standalone SBT project with ScalaTest tests
Scala
1
star
57

domain-crawler

A domain crawler that crawls whois information of domains
Python
1
star