From c3585c73460c3684ce448ab9105d875dd01ab2eb Mon Sep 17 00:00:00 2001 From: "C.T. Lin" Date: Fri, 3 Jun 2016 13:03:08 +0800 Subject: [PATCH] Remove rackt-cli --- .eslintrc.js | 221 ++++++++++++++++++++++++++++++++++++++++++++++ karma.conf.js | 73 +++++++++++++++ package.json | 38 ++++++-- scripts/release | 32 +++++++ webpack.build.js | 40 +++++++++ webpack.config.js | 48 ++++++++++ 6 files changed, 446 insertions(+), 6 deletions(-) create mode 100644 .eslintrc.js create mode 100644 karma.conf.js create mode 100755 scripts/release create mode 100644 webpack.build.js create mode 100644 webpack.config.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000000..7fc6fde5b9 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,221 @@ +module.exports = { + "parser": "babel-eslint", // https://github.com/babel/babel-eslint + "plugins": [ + "react" // https://github.com/yannickcr/eslint-plugin-react + ], + "env": { // http://eslint.org/docs/user-guide/configuring.html#specifying-environments + "browser": true, // browser global variables + "node": true // Node.js global variables and Node.js-specific rules + }, + "ecmaFeatures": { + "arrowFunctions": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": false, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": false, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "spread": true, + "superInFunctions": true, + "templateStrings": true, + "jsx": true + }, + "rules": { +/** + * Strict mode + */ + // babel inserts "use strict"; for us + "strict": [2, "never"], // http://eslint.org/docs/rules/strict + +/** + * ES6 + */ + "no-var": 2, // http://eslint.org/docs/rules/no-var + "prefer-const": 2, // http://eslint.org/docs/rules/prefer-const + +/** + * Variables + */ + "no-shadow": 2, // http://eslint.org/docs/rules/no-shadow + "no-shadow-restricted-names": 2, // http://eslint.org/docs/rules/no-shadow-restricted-names + "no-unused-vars": [2, { // http://eslint.org/docs/rules/no-unused-vars + "vars": "local", + "args": "after-used" + }], + "no-use-before-define": 2, // http://eslint.org/docs/rules/no-use-before-define + +/** + * Possible errors + */ + "comma-dangle": [2, "never"], // http://eslint.org/docs/rules/comma-dangle + "no-cond-assign": [2, "except-parens"], // http://eslint.org/docs/rules/no-cond-assign + "no-console": 1, // http://eslint.org/docs/rules/no-console + "no-debugger": 1, // http://eslint.org/docs/rules/no-debugger + "no-alert": 1, // http://eslint.org/docs/rules/no-alert + "no-constant-condition": 1, // http://eslint.org/docs/rules/no-constant-condition + "no-dupe-keys": 2, // http://eslint.org/docs/rules/no-dupe-keys + "no-duplicate-case": 2, // http://eslint.org/docs/rules/no-duplicate-case + "no-empty": 2, // http://eslint.org/docs/rules/no-empty + "no-ex-assign": 2, // http://eslint.org/docs/rules/no-ex-assign + "no-extra-boolean-cast": 0, // http://eslint.org/docs/rules/no-extra-boolean-cast + "no-extra-semi": 2, // http://eslint.org/docs/rules/no-extra-semi + "no-func-assign": 2, // http://eslint.org/docs/rules/no-func-assign + "no-inner-declarations": 2, // http://eslint.org/docs/rules/no-inner-declarations + "no-invalid-regexp": 2, // http://eslint.org/docs/rules/no-invalid-regexp + "no-irregular-whitespace": 2, // http://eslint.org/docs/rules/no-irregular-whitespace + "no-obj-calls": 2, // http://eslint.org/docs/rules/no-obj-calls + "no-sparse-arrays": 2, // http://eslint.org/docs/rules/no-sparse-arrays + "no-unreachable": 2, // http://eslint.org/docs/rules/no-unreachable + "use-isnan": 2, // http://eslint.org/docs/rules/use-isnan + "block-scoped-var": 2, // http://eslint.org/docs/rules/block-scoped-var + +/** + * Best practices + */ + "consistent-return": 2, // http://eslint.org/docs/rules/consistent-return + "curly": [2, "multi-line"], // http://eslint.org/docs/rules/curly + "default-case": 2, // http://eslint.org/docs/rules/default-case + "dot-notation": [2, { // http://eslint.org/docs/rules/dot-notation + "allowKeywords": true + }], + "eqeqeq": 2, // http://eslint.org/docs/rules/eqeqeq + "guard-for-in": 2, // http://eslint.org/docs/rules/guard-for-in + "no-caller": 2, // http://eslint.org/docs/rules/no-caller + "no-else-return": 2, // http://eslint.org/docs/rules/no-else-return + "no-eq-null": 2, // http://eslint.org/docs/rules/no-eq-null + "no-eval": 2, // http://eslint.org/docs/rules/no-eval + "no-extend-native": 2, // http://eslint.org/docs/rules/no-extend-native + "no-extra-bind": 2, // http://eslint.org/docs/rules/no-extra-bind + "no-fallthrough": 2, // http://eslint.org/docs/rules/no-fallthrough + "no-floating-decimal": 2, // http://eslint.org/docs/rules/no-floating-decimal + "no-implied-eval": 2, // http://eslint.org/docs/rules/no-implied-eval + "no-lone-blocks": 2, // http://eslint.org/docs/rules/no-lone-blocks + "no-loop-func": 2, // http://eslint.org/docs/rules/no-loop-func + "no-multi-str": 2, // http://eslint.org/docs/rules/no-multi-str + "no-native-reassign": 2, // http://eslint.org/docs/rules/no-native-reassign + "no-new": 2, // http://eslint.org/docs/rules/no-new + "no-new-func": 2, // http://eslint.org/docs/rules/no-new-func + "no-new-wrappers": 2, // http://eslint.org/docs/rules/no-new-wrappers + "no-octal": 2, // http://eslint.org/docs/rules/no-octal + "no-octal-escape": 2, // http://eslint.org/docs/rules/no-octal-escape + "no-param-reassign": 2, // http://eslint.org/docs/rules/no-param-reassign + "no-proto": 2, // http://eslint.org/docs/rules/no-proto + "no-redeclare": 2, // http://eslint.org/docs/rules/no-redeclare + "no-return-assign": 2, // http://eslint.org/docs/rules/no-return-assign + "no-script-url": 2, // http://eslint.org/docs/rules/no-script-url + "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare + "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences + "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal + "no-with": 2, // http://eslint.org/docs/rules/no-with + "radix": 2, // http://eslint.org/docs/rules/radix + "vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top + "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife + "yoda": 2, // http://eslint.org/docs/rules/yoda + +/** + * Style + */ + "indent": [2, 2], // http://eslint.org/docs/rules/indent + "brace-style": [2, // http://eslint.org/docs/rules/brace-style + "1tbs", { + "allowSingleLine": true + }], + "quotes": [ + 2, "single", "avoid-escape" // http://eslint.org/docs/rules/quotes + ], + "camelcase": [2, { // http://eslint.org/docs/rules/camelcase + "properties": "never" + }], + "comma-spacing": [2, { // http://eslint.org/docs/rules/comma-spacing + "before": false, + "after": true + }], + "comma-style": [2, "last"], // http://eslint.org/docs/rules/comma-style + "eol-last": 2, // http://eslint.org/docs/rules/eol-last + "func-names": 1, // http://eslint.org/docs/rules/func-names + "key-spacing": [2, { // http://eslint.org/docs/rules/key-spacing + "beforeColon": false, + "afterColon": true + }], + "new-cap": [2, { // http://eslint.org/docs/rules/new-cap + "newIsCap": true + }], + "no-multiple-empty-lines": [2, { // http://eslint.org/docs/rules/no-multiple-empty-lines + "max": 2 + }], + "no-nested-ternary": 2, // http://eslint.org/docs/rules/no-nested-ternary + "no-new-object": 2, // http://eslint.org/docs/rules/no-new-object + "no-spaced-func": 2, // http://eslint.org/docs/rules/no-spaced-func + "no-trailing-spaces": 2, // http://eslint.org/docs/rules/no-trailing-spaces + "no-extra-parens": [2, "functions"], // http://eslint.org/docs/rules/no-extra-parens + "no-underscore-dangle": 0, // http://eslint.org/docs/rules/no-underscore-dangle + "one-var": [2, "never"], // http://eslint.org/docs/rules/one-var + "padded-blocks": [2, "never"], // http://eslint.org/docs/rules/padded-blocks + "semi": [2, "always"], // http://eslint.org/docs/rules/semi + "semi-spacing": [2, { // http://eslint.org/docs/rules/semi-spacing + "before": false, + "after": true + }], + "space-after-keywords": 2, // http://eslint.org/docs/rules/space-after-keywords + "space-before-blocks": 2, // http://eslint.org/docs/rules/space-before-blocks + "space-before-function-paren": [2, "never"], // http://eslint.org/docs/rules/space-before-function-paren + "space-infix-ops": 2, // http://eslint.org/docs/rules/space-infix-ops + "space-return-throw-case": 2, // http://eslint.org/docs/rules/space-return-throw-case + "spaced-comment": [2, "always", {// http://eslint.org/docs/rules/spaced-comment + "exceptions": ["-", "+"], + "markers": ["=", "!"] // space here to support sprockets directives + }], + +/** + * JSX style + */ + "react/display-name": 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/display-name.md + "react/jsx-boolean-value": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md + "react/jsx-quotes": [2, "double"], // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-quotes.md + "react/jsx-no-undef": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-undef.md + "react/jsx-sort-props": 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-props.md + "react/jsx-sort-prop-types": 0, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-sort-prop-types.md + "react/jsx-uses-react": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-react.md + "react/jsx-uses-vars": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-uses-vars.md + "react/no-did-mount-set-state": [2, "allow-in-func"], // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-mount-set-state.md + "react/no-did-update-set-state": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-did-update-set-state.md + "react/no-multi-comp": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md + "react/no-unknown-property": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-unknown-property.md + "react/prop-types": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prop-types.md + "react/react-in-jsx-scope": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md + "react/self-closing-comp": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md + "react/wrap-multilines": 2, // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/wrap-multilines.md + "react/sort-comp": [2, { // https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md + "order": [ + "displayName", + "propTypes", + "contextTypes", + "childContextTypes", + "mixins", + "statics", + "defaultProps", + "constructor", + "getDefaultProps", + "getInitialState", + "getChildContext", + "componentWillMount", + "componentDidMount", + "componentWillReceiveProps", + "shouldComponentUpdate", + "componentWillUpdate", + "componentDidUpdate", + "componentWillUnmount", + "/^handle.+$/", + "/^set.+$/", + "/^get.+$/", + "/^render.+$/", + "render" + ] + }] + } +} diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000000..44f6da90d1 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,73 @@ +var fs = require('fs'); +var path = require('path'); +var REGEX_TEST = /\-test\.js$/; + +function findTests(dir) { + var tests = []; + fs.readdirSync(dir).forEach(function (file) { + file = path.resolve(dir, file); + var stat = fs.statSync(file); + if (stat && stat.isDirectory()) { + tests = tests.concat(findTests(file)); + } else if (REGEX_TEST.test(file)) { + tests.push(file); + } + }); + return tests; +} + +var tests = findTests(path.resolve(process.cwd(), 'lib')); + +module.exports = function(config) { + var conf = { + basePath: '', + + frameworks: ['mocha'], + + files: tests, + + preprocessors: {}, + + reporters: ['dots'], + + port: 9876, + + colors: true, + + logLevel: config.LOG_INFO, + + autoWatch: true, + + browsers: ['Firefox'], + + captureTimeout: 60000, + + singleRun: true, + + webpack: { + cache: true, + devtool: 'source-map', + module: { + loaders: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader' + } + ] + } + }, + + webpackServer: { + stats: { + colors: true + } + } + }; + + tests.forEach(function (test) { + conf.preprocessors[test] = ['webpack', 'sourcemap']; + }); + + config.set(conf); +}; diff --git a/package.json b/package.json index 0f28abbc1e..7ac89d9f93 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,18 @@ "description": "React tabs component", "main": "lib/main.js", "scripts": { - "test": "./node_modules/.bin/rackt test --single-run --browsers Firefox", - "start": "./node_modules/.bin/rackt server" + "clean": "rimraf build", + "build:commonjs": "babel -d build/lib ./lib", + "build:umd": "webpack --devtool source-map --config webpack.build.js", + "build:umd:min": "MINIFY=1 webpack --devtool source-map --config webpack.build.js", + "bundle": "mkdir -p dist && npm run build:umd && npm run build:umd:min", + "copy:package": "cp README.md build/ && node -p 'p=require(\"./package\");p.scripts=p.devDependencies=undefined;JSON.stringify(p,null,2)' > build/package.json", + "build": "npm run clean && npm run build:commonjs && npm run bundle && npm run copy:package", + "prepublish": "npm run clean && npm run build", + "lint": "eslint lib examples", + "testonly": "NODE_ENV=test karma start", + "test": "npm run lint && npm run testonly", + "start": "webpack-dev-server --inline --content-base examples/" }, "repository": { "type": "git", @@ -28,14 +38,30 @@ "react-dom": "^0.14.7" }, "devDependencies": { - "rackt-cli": "^0.5.4", + "babel": "5.8.23", + "babel-core": "5.8.25", + "babel-eslint": "4.1.8", + "babel-loader": "5.3.2", + "eslint": "^1.10.3", + "eslint-plugin-react": "3.5.1", + "karma": "0.13.19", + "karma-cli": "0.1.1", + "karma-firefox-launcher": "0.1.6", + "karma-mocha": "0.2.0", + "karma-sourcemap-loader": "0.3.6", + "karma-webpack": "1.7.0", + "mocha": "2.3.3", "react": "^0.14.7", + "react-addons-test-utils": "^0.14.7", "react-dom": "^0.14.7", - "react-modal": "rackt/react-modal", - "react-addons-test-utils": "^0.14.7" + "react-modal": "reactjs/react-modal", + "rf-release": "mzabriskie/rf-release", + "rimraf": "^2.5.2", + "webpack": "^1.13.1", + "webpack-dev-server": "^1.12.0" }, "dependencies": { "classnames": "^2.2", "js-stylesheet": "^0.0.1" } -} \ No newline at end of file +} diff --git a/scripts/release b/scripts/release new file mode 100755 index 0000000000..a43885c05c --- /dev/null +++ b/scripts/release @@ -0,0 +1,32 @@ +#!/bin/bash + +if [ "$1" == "--preview" ] || [ "$1" == "-P" ] || [ "$1" == "-p" ]; then + # Preview release + node_modules/rf-release/node_modules/.bin/changelog -t preview -s +else + # build task has to be run prior to release module + # the release module is what prompts for next version number + # version is needed in order to update the package.json generated by build task + # we are left prompting for version, and updating build/package.json ourselves + # the version gathered here can then be provided to the release module + + update_version() { + echo "$(node -p "p=require('./${1}');p.version='${2}';JSON.stringify(p,null,2)")" > $1 + echo "Updated ${1} version to ${2}" + } + + current_version=$(node -p "require('./package').version") + + printf "Next version (current is $current_version)? " + read next_version + + if ! [[ $next_version =~ ^[0-9]\.[0-9]+\.[0-9](-.+)? ]]; then + echo "Version must be a valid semver string, e.g. 1.0.2 or 2.3.0-beta.1" + exit 1 + fi + + # Release to npm + npm run build + update_version 'build/package.json' $next_version + node_modules/.bin/release -v $next_version -f ./build +fi diff --git a/webpack.build.js b/webpack.build.js new file mode 100644 index 0000000000..743ee3ba26 --- /dev/null +++ b/webpack.build.js @@ -0,0 +1,40 @@ +var path = require('path'); +var webpack = require('webpack'); +var BASE_DIR = process.cwd(); +var COMPONENT_FILE = 'react-tabs'; +var COMPONENT_NAME = 'ReactTabs'; +var plugins = []; + +function getPackageMain() { + return require(path.resolve(BASE_DIR, 'package.json')).main; +} + +if (process.env.MINIFY) { + plugins.push( + new webpack.optimize.UglifyJsPlugin() + ); + COMPONENT_FILE += '.min'; +} + +module.exports = { + entry: path.resolve(BASE_DIR, getPackageMain()), + output: { + filename: path.resolve(BASE_DIR, 'dist/' + COMPONENT_FILE + '.js'), + library: COMPONENT_NAME, + libraryTarget: 'umd' + }, + externals: { + 'react': 'React', + 'react-dom': 'ReactDOM' + }, + module: { + loaders: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader' + } + ] + }, + plugins: plugins +}; diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000000..57c306186a --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,48 @@ +var fs = require('fs'); +var path = require('path'); +var webpack = require('webpack'); +var EXAMPLES_DIR = path.resolve(process.cwd(), 'examples'); + +function buildEntries() { + return fs.readdirSync(EXAMPLES_DIR).reduce(function (entries, dir) { + if (dir === 'build') { + return entries; + } + + var isDraft = dir.charAt(0) === '_'; + var isDirectory = fs.lstatSync(path.join(EXAMPLES_DIR, dir)).isDirectory(); + + if (!isDraft && isDirectory) { + entries[dir] = path.join(EXAMPLES_DIR, dir, 'app.js'); + } + + return entries; + }, {}); +} + +module.exports = { + + entry: buildEntries(), + + output: { + filename: '[name].js', + chunkFilename: '[id].chunk.js', + path: 'examples/__build__', + publicPath: '/__build__/' + }, + + module: { + loaders: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader' + } + ] + }, + + plugins: [ + new webpack.optimize.CommonsChunkPlugin('shared.js') + ] + +};