From d8afce89647c7ec602c46c864a69d4aeadb599bc Mon Sep 17 00:00:00 2001 From: Alexey Kasyanchuk Date: Wed, 31 Jan 2018 19:02:28 +0300 Subject: [PATCH] web -> desktop --- .babelrc | 18 + .editorconfig | 13 + .gitignore | 15 +- LICENSE | 9 + README.md | 102 + app/app.html | 14 + btsearch.sql | 118 - build/start.js | 20 + build/webpack.app.config.js | 16 + build/webpack.base.config.js | 40 + build/webpack.e2e.config.js | 29 + build/webpack.unit.config.js | 29 + config/env.js | 28 - config/env_development.json | 4 + config/env_production.json | 4 + config/env_test.json | 4 + config/jest/cssTransform.js | 12 - config/jest/fileTransform.js | 10 - config/paths.js | 45 - config/polyfills.js | 14 - config/webpack.config.dev.js | 208 - config/webpack.config.prod.js | 277 - crontab | 17 - deploy | 8 - e2e/hello_world.e2e.js | 12 + e2e/utils.js | 26 + index-block.html | 10 - index.mod.js | 17 - package-lock.json | 9322 +++++++++++++++++ package.json | 192 +- patches/bad.js | 46 - patches/clear.js | 38 - patches/patch1.js | 34 - phantom.js | 27 - public/favicon.ico | Bin 67646 -> 0 bytes public/index.html | 13 - resources/icon.icns | Bin 0 -> 82844 bytes resources/icon.ico | Bin 0 -> 193249 bytes resources/icons/512x512.png | Bin 0 -> 31131 bytes scripts/build.js | 224 - scripts/start.js | 315 - scripts/test.js | 31 - sphinx.conf | 147 - src/app.js | 55 - src/{ => app}/admin-page.js | 0 src/{ => app}/app.css | 0 src/app/app.js | 86 + src/{ => app}/bad-words.js | 0 src/{ => app}/component.js | 0 src/{ => app}/content.js | 0 src/{ => app}/css/izi/animations.css | 0 src/{ => app}/css/izi/components.css | 0 src/{ => app}/css/izi/flex.css | 0 src/{ => app}/css/izi/inputs.css | 0 src/{ => app}/css/izi/izi.css | 0 src/{ => app}/css/izi/material-palette.css | 0 src/{ => app}/dmca-page.js | 0 src/{ => app}/footer.js | 1 - src/{ => app}/format-bytes.js | 0 src/{ => app}/images/no-image-icon.png | Bin src/{ => app}/images/pirate-mod.jpg | Bin src/{ => app}/index-page.js | 2 +- src/{ => app}/index.css | 0 src/{ => app}/index.js | 2 +- src/{ => app}/input-files-filter.js | 2 +- src/app/input-range.css | 83 + src/{ => app}/input-size.js | 2 +- src/{ => app}/page.js | 0 src/{ => app}/pages-pie.js | 0 src/{ => app}/rating.js | 0 src/{ => app}/recent-torrents.js | 0 src/{ => app}/registerServiceWorker.js | 0 src/{ => app}/router.js | 45 +- src/{ => app}/search-advanced-controls.js | 0 src/{ => app}/search-results.js | 0 src/{ => app}/search.js | 37 +- src/{ => app}/top-page.js | 0 src/{ => app}/torrent-page.js | 4 + src/{ => app}/torrent.js | 0 src/{ => app}/touch.js | 0 src/background/background.js | 311 + {bt => src/background/bt}/client.js | 0 {bt => src/background/bt}/cpu-usage.js | 0 {bt => src/background/bt}/peer-queue.js | 0 {bt => src/background/bt}/spider.js | 20 +- {bt => src/background/bt}/table.js | 0 {bt => src/background/bt}/token.js | 0 .../background/bt}/udp-tracker-request.js | 0 {bt => src/background/bt}/wire.js | 0 config.js => src/background/config.js | 2 +- src/background/config.json | 3 + src/background/helpers/window.js | 84 + src/background/menu/dev_menu_template.js | 28 + src/background/menu/edit_menu_template.js | 12 + index.js => src/background/spider.js | 285 +- 95 files changed, 10679 insertions(+), 1893 deletions(-) create mode 100644 .babelrc create mode 100644 .editorconfig create mode 100644 LICENSE create mode 100644 README.md create mode 100644 app/app.html delete mode 100644 btsearch.sql create mode 100644 build/start.js create mode 100644 build/webpack.app.config.js create mode 100644 build/webpack.base.config.js create mode 100644 build/webpack.e2e.config.js create mode 100644 build/webpack.unit.config.js delete mode 100644 config/env.js create mode 100644 config/env_development.json create mode 100644 config/env_production.json create mode 100644 config/env_test.json delete mode 100644 config/jest/cssTransform.js delete mode 100644 config/jest/fileTransform.js delete mode 100644 config/paths.js delete mode 100644 config/polyfills.js delete mode 100644 config/webpack.config.dev.js delete mode 100644 config/webpack.config.prod.js delete mode 100644 crontab delete mode 100755 deploy create mode 100644 e2e/hello_world.e2e.js create mode 100644 e2e/utils.js delete mode 100644 index-block.html delete mode 100644 index.mod.js create mode 100644 package-lock.json delete mode 100644 patches/bad.js delete mode 100644 patches/clear.js delete mode 100644 patches/patch1.js delete mode 100644 phantom.js delete mode 100644 public/favicon.ico delete mode 100644 public/index.html create mode 100644 resources/icon.icns create mode 100644 resources/icon.ico create mode 100644 resources/icons/512x512.png delete mode 100644 scripts/build.js delete mode 100644 scripts/start.js delete mode 100644 scripts/test.js delete mode 100644 sphinx.conf delete mode 100644 src/app.js rename src/{ => app}/admin-page.js (100%) rename src/{ => app}/app.css (100%) create mode 100644 src/app/app.js rename src/{ => app}/bad-words.js (100%) rename src/{ => app}/component.js (100%) rename src/{ => app}/content.js (100%) rename src/{ => app}/css/izi/animations.css (100%) rename src/{ => app}/css/izi/components.css (100%) rename src/{ => app}/css/izi/flex.css (100%) rename src/{ => app}/css/izi/inputs.css (100%) rename src/{ => app}/css/izi/izi.css (100%) rename src/{ => app}/css/izi/material-palette.css (100%) rename src/{ => app}/dmca-page.js (100%) rename src/{ => app}/footer.js (89%) rename src/{ => app}/format-bytes.js (100%) rename src/{ => app}/images/no-image-icon.png (100%) rename src/{ => app}/images/pirate-mod.jpg (100%) rename src/{ => app}/index-page.js (97%) rename src/{ => app}/index.css (100%) rename src/{ => app}/index.js (89%) rename src/{ => app}/input-files-filter.js (98%) create mode 100644 src/app/input-range.css rename src/{ => app}/input-size.js (98%) rename src/{ => app}/page.js (100%) rename src/{ => app}/pages-pie.js (100%) rename src/{ => app}/rating.js (100%) rename src/{ => app}/recent-torrents.js (100%) rename src/{ => app}/registerServiceWorker.js (100%) rename src/{ => app}/router.js (54%) rename src/{ => app}/search-advanced-controls.js (100%) rename src/{ => app}/search-results.js (100%) rename src/{ => app}/search.js (93%) rename src/{ => app}/top-page.js (100%) rename src/{ => app}/torrent-page.js (98%) rename src/{ => app}/torrent.js (100%) rename src/{ => app}/touch.js (100%) create mode 100644 src/background/background.js rename {bt => src/background/bt}/client.js (100%) rename {bt => src/background/bt}/cpu-usage.js (100%) rename {bt => src/background/bt}/peer-queue.js (100%) rename {bt => src/background/bt}/spider.js (94%) rename {bt => src/background/bt}/table.js (100%) rename {bt => src/background/bt}/token.js (100%) rename {bt => src/background/bt}/udp-tracker-request.js (100%) rename {bt => src/background/bt}/wire.js (100%) rename config.js => src/background/config.js (96%) create mode 100644 src/background/config.json create mode 100644 src/background/helpers/window.js create mode 100644 src/background/menu/dev_menu_template.js create mode 100644 src/background/menu/edit_menu_template.js rename index.js => src/background/spider.js (76%) diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..ddf3d70 --- /dev/null +++ b/.babelrc @@ -0,0 +1,18 @@ +{ + "presets": [ + [ + "@babel/env", + { + "targets": { + "browsers": "last 2 Chrome versions", + "node": "current" + } + } + ], + "@babel/react", + "@babel/stage-0" + ], + "plugins": [ + ["transform-object-rest-spread", { "useBuiltIns": true }] + ] +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5d12634 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitignore b/.gitignore index 2490548..601aee1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ -node_modules/* -build/ -config.json \ No newline at end of file +node_modules +.DS_Store +Thumbs.db +*.log + +/dist +/temp + +# ignore everything in 'app' folder what had been generated from 'src' folder +/app/app.js +/app/background.js +/app/**/*.map diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f76ac44 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright (c) 2015-2017 Jakub Szwacz + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7846e07 --- /dev/null +++ b/README.md @@ -0,0 +1,102 @@ +# electron-boilerplate + +A minimalistic boilerplate for [Electron runtime](http://electron.atom.io). Tested on Windows, macOS and Linux. + +This project contains only bare minimum of dependencies, to provide you with nice development environment. Doesn't impose on you any frontend technologies, so you can pick your favourite. + +# Quick start + +Make sure you have [Node.js](https://nodejs.org) installed, then type the following commands known to every Node developer... +``` +git clone https://github.com/szwacz/electron-boilerplate.git +cd electron-boilerplate +npm install +npm start +``` +...and you have a running desktop application on your screen. + +# Structure of the project + +The application consists of two main folders... + +`src` - files within this folder get transpiled or compiled (because Electron can't use them directly). + +`app` - contains all static assets which don't need any pre-processing. Put here images, CSSes, HTMLs, etc. + +The build process compiles the content of the `src` folder and puts it into the `app` folder, so after the build has finished, your `app` folder contains the full, runnable application. + +Treat `src` and `app` folders like two halves of one bigger thing. + +The drawback of this design is that `app` folder contains some files which should be git-ignored and some which shouldn't (see `.gitignore` file). But this two-folders split makes development builds much, much faster. + +# Development + +## Starting the app + +``` +npm start +``` + +## The build pipeline + +Build process uses [Webpack](https://webpack.js.org/). The entry-points are `src/background.js` and `src/app.js`. Webpack will follow all `import` statements starting from those files and compile code of the whole dependency tree into one `.js` file for each entry point. + +[Babel](http://babeljs.io/) is also utilised, but mainly for its great error messages. Electron under the hood runs latest Chromium, hence most of the new JavaScript features are already natively supported. + +## Environments + +Environmental variables are done in a bit different way (not via `process.env`). Env files are plain JSONs in `config` directory, and build process dynamically links one of them as an `env` module. You can import it wherever in code you need access to the environment. +```js +import env from "env"; +console.log(env.name); +``` + +## Upgrading Electron version + +To do so edit `package.json`: +```json +"devDependencies": { + "electron": "1.7.9" +} +``` +*Side note:* [Electron authors recommend](http://electron.atom.io/docs/tutorial/electron-versioning/) to use fixed version here. + +## Adding npm modules to your app + +Remember to respect the split between `dependencies` and `devDependencies` in `package.json` file. Your distributable app will contain modules listed in `dependencies` after running the release script. + +*Side note:* If the module you want to use in your app is a native one (not pure JavaScript but compiled binary) you should first run `npm install name_of_npm_module` and then `npm run postinstall` to rebuild the module for Electron. You need to do this once after you're first time installing the module. Later on, the postinstall script will fire automatically with every `npm install`. + +# Testing + +Run all tests: +``` +npm test +``` + +## Unit + +``` +npm run unit +``` +Using [electron-mocha](https://github.com/jprichardson/electron-mocha) test runner with the [Chai](http://chaijs.com/api/assert/) assertion library. You can put your spec files wherever you want within the `src` directory, just name them with the `.spec.js` extension. + +## End to end + +``` +npm run e2e +``` +Using [Mocha](https://mochajs.org/) and [Spectron](http://electron.atom.io/spectron/). This task will run all files in `e2e` directory with `.e2e.js` extension. + +# Making a release + +To package your app into an installer use command: +``` +npm run release +``` + +Once the packaging process finished, the `dist` directory will contain your distributable file. + +We use [electron-builder](https://github.com/electron-userland/electron-builder) to handle the packaging process. It has a lot of [customization options](https://www.electron.build/configuration/configuration), which you can declare under `"build"` key in `package.json`. + +You can package your app cross-platform from a single operating system, [electron-builder kind of supports this](https://www.electron.build/multi-platform-build), but there are limitations and asterisks. That's why this boilerplate doesn't do that by default. diff --git a/app/app.html b/app/app.html new file mode 100644 index 0000000..2eb4aa1 --- /dev/null +++ b/app/app.html @@ -0,0 +1,14 @@ + + + + + Torrent Search + + + +
+
+ + + + diff --git a/btsearch.sql b/btsearch.sql deleted file mode 100644 index d486b18..0000000 --- a/btsearch.sql +++ /dev/null @@ -1,118 +0,0 @@ --- MySQL dump 10.16 Distrib 10.1.20-MariaDB, for Linux (x86_64) --- --- Host: localhost Database: localhost --- ------------------------------------------------------ --- Server version 10.1.20-MariaDB - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `files` --- - -DROP TABLE IF EXISTS `files`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `files` ( - `hash` char(40) DEFAULT NULL, - `path` text, - `size` bigint(20) unsigned DEFAULT NULL, - `fileid` int(10) unsigned NOT NULL AUTO_INCREMENT, - PRIMARY KEY (`fileid`), - KEY `hash` (`hash`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `sphinx_counter` --- - -DROP TABLE IF EXISTS `sphinx_counter`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `sphinx_counter` ( - `counter_id` int(11) NOT NULL, - `max_doc_id` int(10) unsigned NOT NULL, - PRIMARY KEY (`counter_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `statistic` --- - -DROP TABLE IF EXISTS `statistic`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `statistic` ( - `size` bigint(20) unsigned DEFAULT NULL, - `files` bigint(20) unsigned DEFAULT NULL, - `torrents` int(10) unsigned DEFAULT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `torrents` --- - -DROP TABLE IF EXISTS `torrents`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `torrents` ( - `hash` char(40) NOT NULL, - `name` text, - `size` bigint(20) unsigned DEFAULT NULL, - `files` int(10) unsigned DEFAULT NULL, - `piecelength` int(10) unsigned DEFAULT NULL, - `added` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `ipv4` char(15) DEFAULT NULL, - `port` smallint(5) unsigned DEFAULT NULL, - `contentType` enum('video','audio','pictures','books','application','archive','disc') DEFAULT NULL, - `contentCategory` varchar(32) DEFAULT NULL, - `seeders` int(10) unsigned DEFAULT NULL, - `leechers` int(10) unsigned DEFAULT NULL, - `completed` int(10) unsigned DEFAULT NULL, - `torrentid` int(10) unsigned NOT NULL AUTO_INCREMENT, - `trackersChecked` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `good` int(10) unsigned DEFAULT '0', - `bad` int(10) unsigned DEFAULT '0', - PRIMARY KEY (`hash`), - UNIQUE KEY `torrentid` (`torrentid`), - KEY `added` (`added`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `torrents_actions` --- - -DROP TABLE IF EXISTS `torrents_actions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `torrents_actions` ( - `hash` char(40) NOT NULL, - `action` varchar(32) DEFAULT NULL, - `ipv4` char(15) DEFAULT NULL, - KEY `hash` (`hash`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- Dump completed on 2017-01-30 12:10:40 diff --git a/build/start.js b/build/start.js new file mode 100644 index 0000000..38bfc16 --- /dev/null +++ b/build/start.js @@ -0,0 +1,20 @@ +const childProcess = require("child_process"); +const electron = require("electron"); +const webpack = require("webpack"); +const config = require("./webpack.app.config"); + +const env = "development"; +const compiler = webpack(config(env)); +let electronStarted = false; + +const watching = compiler.watch({}, (err, stats) => { + if (!err && !stats.hasErrors() && !electronStarted) { + electronStarted = true; + + childProcess + .spawn(electron, ["."], { stdio: "inherit" }) + .on("close", () => { + watching.close(); + }); + } +}); diff --git a/build/webpack.app.config.js b/build/webpack.app.config.js new file mode 100644 index 0000000..9d66701 --- /dev/null +++ b/build/webpack.app.config.js @@ -0,0 +1,16 @@ +const path = require("path"); +const merge = require("webpack-merge"); +const base = require("./webpack.base.config"); + +module.exports = env => { + return merge(base(env), { + entry: { + background: "./src/background/background.js", + app: "./src/app/index.js" + }, + output: { + filename: "[name].js", + path: path.resolve(__dirname, "../app") + } + }); +}; diff --git a/build/webpack.base.config.js b/build/webpack.base.config.js new file mode 100644 index 0000000..f9d7863 --- /dev/null +++ b/build/webpack.base.config.js @@ -0,0 +1,40 @@ +const path = require("path"); +const nodeExternals = require("webpack-node-externals"); +const FriendlyErrorsWebpackPlugin = require("friendly-errors-webpack-plugin"); + +module.exports = env => { + return { + target: "node", + node: { + __dirname: false, + __filename: false + }, + externals: [nodeExternals()], + resolve: { + alias: { + env: path.resolve(__dirname, `../config/env_${env}.json`) + } + }, + devtool: "source-map", + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: ["babel-loader"] + }, + { + test: /\.css$/, + use: ["style-loader", "css-loader"] + }, + { + test: /\.(?:ico|gif|png|jpg|jpeg|webp)$/, + use: ['url-loader'] + } + ] + }, + plugins: [ + new FriendlyErrorsWebpackPlugin({ clearConsole: env === "development" }) + ] + }; +}; diff --git a/build/webpack.e2e.config.js b/build/webpack.e2e.config.js new file mode 100644 index 0000000..95ec305 --- /dev/null +++ b/build/webpack.e2e.config.js @@ -0,0 +1,29 @@ +const merge = require("webpack-merge"); +const jetpack = require("fs-jetpack"); +const base = require("./webpack.base.config"); + +// Test files are scattered through the whole project. Here we're searching +// for them and generating entry file for webpack. + +const e2eDir = jetpack.cwd("e2e"); +const tempDir = jetpack.cwd("temp"); +const entryFilePath = tempDir.path("e2e_entry.js"); + +const entryFileContent = e2eDir + .find({ matching: "*.e2e.js" }) + .reduce((fileContent, path) => { + const normalizedPath = path.replace(/\\/g, "/"); + return `${fileContent}import "../e2e/${normalizedPath}";\n`; + }, ""); + +jetpack.write(entryFilePath, entryFileContent); + +module.exports = env => { + return merge(base(env), { + entry: entryFilePath, + output: { + filename: "e2e.js", + path: tempDir.path() + } + }); +}; diff --git a/build/webpack.unit.config.js b/build/webpack.unit.config.js new file mode 100644 index 0000000..c34a5a8 --- /dev/null +++ b/build/webpack.unit.config.js @@ -0,0 +1,29 @@ +const merge = require("webpack-merge"); +const jetpack = require("fs-jetpack"); +const base = require("./webpack.base.config"); + +// Test files are scattered through the whole project. Here we're searching +// for them and generating entry file for webpack. + +const srcDir = jetpack.cwd("src"); +const tempDir = jetpack.cwd("temp"); +const entryFilePath = tempDir.path("specs_entry.js"); + +const entryFileContent = srcDir + .find({ matching: "*.spec.js" }) + .reduce((fileContent, path) => { + const normalizedPath = path.replace(/\\/g, "/"); + return `${fileContent}import "../src/${normalizedPath}";\n`; + }, ""); + +jetpack.write(entryFilePath, entryFileContent); + +module.exports = env => { + return merge(base(env), { + entry: entryFilePath, + output: { + filename: "specs.js", + path: tempDir.path() + } + }); +}; diff --git a/config/env.js b/config/env.js deleted file mode 100644 index 5d0ab7b..0000000 --- a/config/env.js +++ /dev/null @@ -1,28 +0,0 @@ -// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be -// injected into the application via DefinePlugin in Webpack configuration. - -var REACT_APP = /^REACT_APP_/i; - -function getClientEnvironment(publicUrl) { - var processEnv = Object - .keys(process.env) - .filter(key => REACT_APP.test(key)) - .reduce((env, key) => { - env[key] = JSON.stringify(process.env[key]); - return env; - }, { - // Useful for determining whether we’re running in production mode. - // Most importantly, it switches React into the correct mode. - 'NODE_ENV': JSON.stringify( - process.env.NODE_ENV || 'development' - ), - // Useful for resolving the correct path to static assets in `public`. - // For example, . - // This should only be used as an escape hatch. Normally you would put - // images into the `src` and `import` them in code to get their paths. - 'PUBLIC_URL': JSON.stringify(publicUrl) - }); - return {'process.env': processEnv}; -} - -module.exports = getClientEnvironment; diff --git a/config/env_development.json b/config/env_development.json new file mode 100644 index 0000000..efb7748 --- /dev/null +++ b/config/env_development.json @@ -0,0 +1,4 @@ +{ + "name": "development", + "description": "Add here any environment specific stuff you like." +} diff --git a/config/env_production.json b/config/env_production.json new file mode 100644 index 0000000..600b2d7 --- /dev/null +++ b/config/env_production.json @@ -0,0 +1,4 @@ +{ + "name": "production", + "description": "Add here any environment specific stuff you like." +} diff --git a/config/env_test.json b/config/env_test.json new file mode 100644 index 0000000..e3956a5 --- /dev/null +++ b/config/env_test.json @@ -0,0 +1,4 @@ +{ + "name": "test", + "description": "Add here any environment specific stuff you like." +} diff --git a/config/jest/cssTransform.js b/config/jest/cssTransform.js deleted file mode 100644 index aa17d12..0000000 --- a/config/jest/cssTransform.js +++ /dev/null @@ -1,12 +0,0 @@ -// This is a custom Jest transformer turning style imports into empty objects. -// http://facebook.github.io/jest/docs/tutorial-webpack.html - -module.exports = { - process() { - return 'module.exports = {};'; - }, - getCacheKey(fileData, filename) { - // The output is always the same. - return 'cssTransform'; - }, -}; diff --git a/config/jest/fileTransform.js b/config/jest/fileTransform.js deleted file mode 100644 index 927eb30..0000000 --- a/config/jest/fileTransform.js +++ /dev/null @@ -1,10 +0,0 @@ -const path = require('path'); - -// This is a custom Jest transformer turning file imports into filenames. -// http://facebook.github.io/jest/docs/tutorial-webpack.html - -module.exports = { - process(src, filename) { - return 'module.exports = ' + JSON.stringify(path.basename(filename)) + ';'; - }, -}; diff --git a/config/paths.js b/config/paths.js deleted file mode 100644 index e831b59..0000000 --- a/config/paths.js +++ /dev/null @@ -1,45 +0,0 @@ -var path = require('path'); -var fs = require('fs'); - -// Make sure any symlinks in the project folder are resolved: -// https://github.com/facebookincubator/create-react-app/issues/637 -var appDirectory = fs.realpathSync(process.cwd()); -function resolveApp(relativePath) { - return path.resolve(appDirectory, relativePath); -} - -// We support resolving modules according to `NODE_PATH`. -// This lets you use absolute paths in imports inside large monorepos: -// https://github.com/facebookincubator/create-react-app/issues/253. - -// It works similar to `NODE_PATH` in Node itself: -// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders - -// We will export `nodePaths` as an array of absolute paths. -// It will then be used by Webpack configs. -// Jest doesn’t need this because it already handles `NODE_PATH` out of the box. - -// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. -// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. -// https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 - -var nodePaths = (process.env.NODE_PATH || '') - .split(process.platform === 'win32' ? ';' : ':') - .filter(Boolean) - .filter(folder => !path.isAbsolute(folder)) - .map(resolveApp); - -// config after eject: we're in ./config/ -module.exports = { - appBuild: resolveApp('build'), - appPublic: resolveApp('public'), - appHtml: resolveApp('public/index.html'), - appIndexJs: resolveApp('src/index.js'), - appPackageJson: resolveApp('package.json'), - appSrc: resolveApp('src'), - yarnLockFile: resolveApp('yarn.lock'), - testsSetup: resolveApp('src/setupTests.js'), - appNodeModules: resolveApp('node_modules'), - ownNodeModules: resolveApp('node_modules'), - nodePaths: nodePaths -}; diff --git a/config/polyfills.js b/config/polyfills.js deleted file mode 100644 index 7e60150..0000000 --- a/config/polyfills.js +++ /dev/null @@ -1,14 +0,0 @@ -if (typeof Promise === 'undefined') { - // Rejection tracking prevents a common issue where React gets into an - // inconsistent state due to an error, but it gets swallowed by a Promise, - // and the user has no idea what causes React's erratic future behavior. - require('promise/lib/rejection-tracking').enable(); - window.Promise = require('promise/lib/es6-extensions.js'); -} - -// fetch() polyfill for making API calls. -require('whatwg-fetch'); - -// Object.assign() is commonly used with React. -// It will use the native implementation if it's present and isn't buggy. -Object.assign = require('object-assign'); diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js deleted file mode 100644 index f2e85f1..0000000 --- a/config/webpack.config.dev.js +++ /dev/null @@ -1,208 +0,0 @@ -var autoprefixer = require('autoprefixer'); -var webpack = require('webpack'); -var HtmlWebpackPlugin = require('html-webpack-plugin'); -var CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); -var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); -var WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); -var getClientEnvironment = require('./env'); -var paths = require('./paths'); - - - -// Webpack uses `publicPath` to determine where the app is being served from. -// In development, we always serve from the root. This makes config easier. -var publicPath = '/'; -// `publicUrl` is just like `publicPath`, but we will provide it to our app -// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript. -// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz. -var publicUrl = ''; -// Get environment variables to inject into our app. -var env = getClientEnvironment(publicUrl); - -// This is the development configuration. -// It is focused on developer experience and fast rebuilds. -// The production configuration is different and lives in a separate file. -module.exports = { - // You may want 'eval' instead if you prefer to see the compiled output in DevTools. - // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343. - devtool: 'cheap-module-source-map', - // These are the "entry points" to our application. - // This means they will be the "root" imports that are included in JS bundle. - // The first two entry points enable "hot" CSS and auto-refreshes for JS. - entry: [ - // Include an alternative client for WebpackDevServer. A client's job is to - // connect to WebpackDevServer by a socket and get notified about changes. - // When you save a file, the client will either apply hot updates (in case - // of CSS changes), or refresh the page (in case of JS changes). When you - // make a syntax error, this client will display a syntax error overlay. - // Note: instead of the default WebpackDevServer client, we use a custom one - // to bring better experience for Create React App users. You can replace - // the line below with these two lines if you prefer the stock client: - // require.resolve('webpack-dev-server/client') + '?/', - // require.resolve('webpack/hot/dev-server'), - require.resolve('react-dev-utils/webpackHotDevClient'), - // We ship a few polyfills by default: - require.resolve('./polyfills'), - // Finally, this is your app's code: - paths.appIndexJs - // We include the app code last so that if there is a runtime error during - // initialization, it doesn't blow up the WebpackDevServer client, and - // changing JS code would still trigger a refresh. - ], - output: { - // Next line is not used in dev but WebpackDevServer crashes without it: - path: paths.appBuild, - // Add /* filename */ comments to generated require()s in the output. - pathinfo: true, - // This does not produce a real file. It's just the virtual path that is - // served by WebpackDevServer in development. This is the JS bundle - // containing code from all our entry points, and the Webpack runtime. - filename: 'static/js/bundle.js', - // This is the URL that app is served from. We use "/" in development. - publicPath: publicPath - }, - resolve: { - // This allows you to set a fallback for where Webpack should look for modules. - // We read `NODE_PATH` environment variable in `paths.js` and pass paths here. - // We use `fallback` instead of `root` because we want `node_modules` to "win" - // if there any conflicts. This matches Node resolution mechanism. - // https://github.com/facebookincubator/create-react-app/issues/253 - fallback: paths.nodePaths, - // These are the reasonable defaults supported by the Node ecosystem. - // We also include JSX as a common component filename extension to support - // some tools, although we do not recommend using it, see: - // https://github.com/facebookincubator/create-react-app/issues/290 - extensions: ['.js', '.json', '.jsx', ''], - alias: { - // Support React Native Web - // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ - 'react-native': 'react-native-web' - } - }, - - module: { - // First, run the linter. - // It's important to do this before Babel processes the JS. - preLoaders: [ - { - test: /\.(js|jsx)$/, - loader: 'eslint', - include: paths.appSrc, - } - ], - loaders: [ - // Default loader: load all assets that are not handled - // by other loaders with the url loader. - // Note: This list needs to be updated with every change of extensions - // the other loaders match. - // E.g., when adding a loader for a new supported file extension, - // we need to add the supported extension to this loader too. - // Add one new line in `exclude` for each loader. - // - // "file" loader makes sure those assets get served by WebpackDevServer. - // When you `import` an asset, you get its (virtual) filename. - // In production, they would get copied to the `build` folder. - // "url" loader works like "file" loader except that it embeds assets - // smaller than specified limit in bytes as data URLs to avoid requests. - // A missing `test` is equivalent to a match. - { - exclude: [ - /\.html$/, - /\.(js|jsx)$/, - /\.css$/, - /\.json$/, - /\.svg$/ - ], - loader: 'url', - query: { - limit: 10000, - name: 'static/media/[name].[hash:8].[ext]' - } - }, - // Process JS with Babel. - { - test: /\.(js|jsx)$/, - include: paths.appSrc, - loader: 'babel', - query: { - - // This is a feature of `babel-loader` for webpack (not Babel itself). - // It enables caching results in ./node_modules/.cache/babel-loader/ - // directory for faster rebuilds. - cacheDirectory: true - } - }, - // "postcss" loader applies autoprefixer to our CSS. - // "css" loader resolves paths in CSS and adds assets as dependencies. - // "style" loader turns CSS into JS modules that inject