From 6a33a8583b6a6ad9b26cf638b41d820d1541adf3 Mon Sep 17 00:00:00 2001 From: Tony Air Date: Mon, 5 Feb 2018 18:11:01 +0700 Subject: [PATCH] Intial commit --- .gitignore | 18 +++ browserconfig.xml | 12 ++ cache.appcache | 10 ++ composer.json | 32 +++++ humans.txt | 11 ++ manifest.json | 49 +++++++ package.json | 110 ++++++++++++++++ phpcs.xml.dist | 25 ++++ phpunit.xml | 18 +++ robots.txt | 7 + site/WebpackTemplateProvider.php | 90 +++++++++++++ site/_config/webpack.yml | 10 ++ site/src/_config/webpack.yml | 10 ++ site/src/favicon.png | Bin 0 -> 9255 bytes site/src/js/_components/_spinner.js | 19 +++ site/src/js/_events.js | 8 ++ .../js/_pageType_and_component_template.js | 88 +++++++++++++ site/src/js/app.js | 38 ++++++ site/src/js/main.js | 38 ++++++ site/src/scss/_layout.scss | 7 + site/src/scss/_variables.scss | 10 ++ site/src/scss/app.scss | 42 ++++++ site/templates/Page.ss | 64 +++++++++ webpack.config.common.js | 122 ++++++++++++++++++ webpack.config.dev.js | 97 ++++++++++++++ webpack.config.prod.js | 102 +++++++++++++++ webpack.configuration.js | 12 ++ 27 files changed, 1049 insertions(+) create mode 100644 .gitignore create mode 100644 browserconfig.xml create mode 100755 cache.appcache create mode 100755 composer.json create mode 100755 humans.txt create mode 100644 manifest.json create mode 100755 package.json create mode 100755 phpcs.xml.dist create mode 100755 phpunit.xml create mode 100755 robots.txt create mode 100644 site/WebpackTemplateProvider.php create mode 100644 site/_config/webpack.yml create mode 100644 site/src/_config/webpack.yml create mode 100644 site/src/favicon.png create mode 100644 site/src/js/_components/_spinner.js create mode 100644 site/src/js/_events.js create mode 100644 site/src/js/_pageType_and_component_template.js create mode 100644 site/src/js/app.js create mode 100644 site/src/js/main.js create mode 100644 site/src/scss/_layout.scss create mode 100644 site/src/scss/_variables.scss create mode 100644 site/src/scss/app.scss create mode 100644 site/templates/Page.ss create mode 100755 webpack.config.common.js create mode 100755 webpack.config.dev.js create mode 100755 webpack.config.prod.js create mode 100755 webpack.configuration.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4a4b0b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +# START Do not modify the lines between here and #END, they will be regenerated by GitIgnoreEditor +/betternavigator +/cms +/debugbar +/framework +/ideannotator +/redirectedurls +/reports +/silverstripe-scaled-uploads +/silverstripe-version-truncator +/siteconfig +# END of GitIgnoreEditor + +/node_modules +/composer.lock +/yarn.lock +/vendor +/site/dist \ No newline at end of file diff --git a/browserconfig.xml b/browserconfig.xml new file mode 100644 index 0000000..36439de --- /dev/null +++ b/browserconfig.xml @@ -0,0 +1,12 @@ + + + + + + + + + #000 + + + diff --git a/cache.appcache b/cache.appcache new file mode 100755 index 0000000..a620a24 --- /dev/null +++ b/cache.appcache @@ -0,0 +1,10 @@ +CACHE MANIFEST + +FALLBACK: +/ +/site/dist/css/app.css +/site/dist/img/logo.png +/site/dist/img/fonts/fontawesome-webfont.woff2?v=4.7.0 +/site/dist/img/fonts/fontawesome-webfont.woff?v=4.7.0 +/site/dist/img/fonts/fontawesome-webfont.ttf?v=4.7.0 +/site/dist/js/app.js \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100755 index 0000000..41733de --- /dev/null +++ b/composer.json @@ -0,0 +1,32 @@ +{ + "name": "silverstripe/installer", + "description": "The SilverStripe webpack boilerplate", + "require": { + "php": ">=5.5.0", + "silverstripe/cms": "*", + "silverstripe/framework": "3.7.x-dev", + "silverstripe/redirectedurls": "*", + "axllent/silverstripe-scaled-uploads": "*", + "jonom/silverstripe-betternavigator": "*", + "axllent/silverstripe-version-truncator": "*" + }, + "require-dev": { + "phpunit/PHPUnit": "~3.7", + "gdmedia/ss-auto-git-ignore": "^1.0", + "axyr/silverstripe-ideannotator": "dev-master", + "lekoala/silverstripe-debugbar": "^1.0" + }, + "scripts": { + "post-update-cmd": "GDM\\SSAutoGitIgnore\\UpdateScript::Go" + }, + "config": { + "process-timeout": 600, + "discard-changes": true + }, + "extra": { + "branch-alias": { + "3.x-dev": "3.6.x-dev" + } + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/humans.txt b/humans.txt new file mode 100755 index 0000000..7c664d2 --- /dev/null +++ b/humans.txt @@ -0,0 +1,11 @@ +/* AUTHOR */ +Name: + +/* TEAM */ +Site: https://bla-bla.com/ + +/* SITE */ +Doctype: HTML5 +IDE: PHPStorm, Sublime Text, Photoshop, Transmit +Framework: SilverStripe +Language: English \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..a216f7a --- /dev/null +++ b/manifest.json @@ -0,0 +1,49 @@ +{ + "name": "SilverStripe", + "short_name": "SilverStripe website", + "description": "", + "dir": "auto", + "lang": "en-US", + "display": "standalone", + "orientation": "any", + "start_url": "/?homescreen=1", + "theme_color": "#000000", + "background_color": "#000000", + "icons": [{ + "src": "/dist/icons/android-chrome-36x36.png", + "sizes": "36x36", + "type": "image/png" + }, { + "src": "/dist/icons/android-chrome-48x48.png", + "sizes": "48x48", + "type": "image/png" + }, { + "src": "/dist/icons/android-chrome-72x72.png", + "sizes": "72x72", + "type": "image/png" + }, { + "src": "/dist/icons/android-chrome-96x96.png", + "sizes": "96x96", + "type": "image/png" + }, { + "src": "/dist/icons/android-chrome-144x144.png", + "sizes": "144x144", + "type": "image/png" + }, { + "src": "/dist/icons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, { + "src": "/dist/icons/android-chrome-256x256.png", + "sizes": "256x256", + "type": "image/png" + }, { + "src": "/dist/icons/android-chrome-384x384.png", + "sizes": "384x384", + "type": "image/png" + }, { + "src": "/dist/icons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + }] +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100755 index 0000000..aa58383 --- /dev/null +++ b/package.json @@ -0,0 +1,110 @@ +{ + "name": "ss-webpack-boilerplate", + "version": "1.0.0", + "description": "Lets you create SilverStripe faster", + "author": "Tony Air ", + "license": "MIT", + "private": false, + "engines": { + "yarn": ">= 1.0.0" + }, + "scripts": { + "start": "cross-env NODE_ENV=development webpack-dev-server -d --config webpack.config.dev.js", + "dash": "cross-env NODE_ENV=development webpack-dashboard -- webpack-dev-server --config webpack.config.dev.js", + "prebuild": "rimraf build", + "build": "cross-env NODE_ENV=production webpack -p --config webpack.config.prod.js --progress" + }, + "dependencies": { + "bootstrap": "twbs/bootstrap#>= 3.1.0", + "favicons-webpack-plugin": "^0.0.7", + "jquery": "^3.3.1", + "js-yaml": "^3.10.0", + "popper": "^1.0.1", + "popper.js": "^1.12.9" + }, + "devDependencies": { + "exports-loader": "^0.7.0", + "favicons-webpack-plugin": "^0.0.7", + "@silverstripe/eslint-config": "0.0.2", + "autoprefixer": "^7.2.5", + "babel-core": "^6.26.0", + "babel-loader": "^7.1.2", + "babel-plugin-transform-react-jsx": "^6.24.1", + "babel-preset-es2015": "^6.24.1", + "babel-preset-react": "^6.24.1", + "babel-preset-stage-2": "^6.24.1", + "browser-sync": "^2.23.6", + "browser-sync-webpack-plugin": "^1.2.0", + "copy-webpack-plugin": "^4.3.1", + "copyfiles": "^1.2.0", + "cross-env": "^5.1.3", + "css-loader": "^0.28.9", + "extract-text-webpack-plugin": "^3.0.2", + "file-loader": "^1.1.5", + "html-webpack-plugin": "^2.30.1", + "laravel-mix": "^1.0", + "lost": "^8.2.0", + "node-sass": "^4.6.1", + "optimize-css-assets-webpack-plugin": "^3.2.0", + "postcss-loader": "^2.0.10", + "react": "^16.2.0", + "react-dom": "^16.2.0", + "react-hot-loader": "^3.1.3", + "redux": "^3.7.2", + "redux-devtools-extension": "^2.13.2", + "resolve-url-loader": "^2.2.1", + "rimraf": "^2.6.2", + "sass-loader": "^6.0.6", + "script-ext-html-webpack-plugin": "^1.8.8", + "style-loader": "^0.19.0", + "svg-url-loader": "^2.3.1", + "uglifyjs-webpack-plugin": "^1.1.6", + "url-loader": "^0.6.2", + "webpack": "^3.8.1", + "webpack-dashboard": "^1.1.1", + "webpack-dev-server": "^2.11.1", + "webpack-manifest-plugin": "^1.3.2", + "webpack-merge": "^4.1.1", + "worker-loader": "^1.1.0" + }, + "stylelint": { + "rules": { + "block-no-empty": null, + "color-no-invalid-hex": true, + "comment-empty-line-before": [ + "always", { + "ignore": [ + "stylelint-commands", + "after-comment" + ] + } + ], + "declaration-colon-space-after": "always", + "indentation": [ + 4, { + "except": [ + "value" + ] + } + ], + "max-empty-lines": 2, + "rule-empty-line-before": [ + "always", { + "except": [ + "first-nested" + ], + "ignore": [ + "after-comment" + ] + } + ], + "unit-whitelist": [ + "em", + "rem", + "%", + "s", + "px" + ] + } + } +} \ No newline at end of file diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100755 index 0000000..8fe95eb --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,25 @@ + + + Coding standard for SilverStripe 3.x + + + */vendor/* + */thirdparty/* + */node_modules/* + + + + + + + + + + + + + + + + + diff --git a/phpunit.xml b/phpunit.xml new file mode 100755 index 0000000..3a1d051 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,18 @@ + + + + cms/tests + framework/tests + + + + + + + + + sanitychecks + + + + diff --git a/robots.txt b/robots.txt new file mode 100755 index 0000000..dfa00d6 --- /dev/null +++ b/robots.txt @@ -0,0 +1,7 @@ +User-agent: * +Allow: / +Crawl-delay: 10 +Disallow: /admin +Disallow: /Security +Sitemap: https://www.bla-bla.org/sitemap.xml +Host: https://www.bla-bla.org \ No newline at end of file diff --git a/site/WebpackTemplateProvider.php b/site/WebpackTemplateProvider.php new file mode 100644 index 0000000..0c94b65 --- /dev/null +++ b/site/WebpackTemplateProvider.php @@ -0,0 +1,90 @@ + 'isActive', + 'WebpackCSS' => 'loadCSS', + 'WebpackJS' => 'loadJS', + ]; + } + + /** + * @var int port number + */ + private static $port = 3000; + + /** + * @var string host name + */ + private static $hostname = 'localhost'; + + /** + * @var string assets static files directory + */ + private static $distDir = 'site/dist'; + + /** + * Load CSS file + * @param $path + */ + public static function loadCSS($path) + { + if (!self::isActive()) { + Requirements::css(self::_toPublicPath($path)); + } + } + + /** + * Load JS file + * @param $path + */ + public static function loadJS($path) + { + $path = self::isActive() ? + self::_toDevServerPath($path) : + self::_toPublicPath($path); + + Requirements::javascript($path); + } + + + /** + * Checks if dev mode is enabled and if webpack server is online + * @return bool + */ + public static function isActive() + { + $class = __CLASS__; + return Director::isDev() && !!@fsockopen( + $class::config()->get('hostname'), + $class::config()->get('port') + ); + } + + protected static function _toDevServerPath($path) + { + $class = __CLASS__; + return sprintf( + 'http://%s:%s/%s', + $class::config()->get('hostname'), + $class::config()->get('port'), + $path + ); + } + + protected static function _toPublicPath($path) + { + $class = __CLASS__; + return $class::config()->get('distDir') . '/' . $path; + } +} diff --git a/site/_config/webpack.yml b/site/_config/webpack.yml new file mode 100644 index 0000000..e610f7a --- /dev/null +++ b/site/_config/webpack.yml @@ -0,0 +1,10 @@ +# that's important to place this file into /site/_config/webpack.yml +# with all configuration variables presented +# Cuz WebPack compiling script use it to set configuration + +WebpackTemplateProvider: + dist: site/dist + hostname: localhost + port: "3000" + pages: site/src/js/types + src: site/src diff --git a/site/src/_config/webpack.yml b/site/src/_config/webpack.yml new file mode 100644 index 0000000..e610f7a --- /dev/null +++ b/site/src/_config/webpack.yml @@ -0,0 +1,10 @@ +# that's important to place this file into /site/_config/webpack.yml +# with all configuration variables presented +# Cuz WebPack compiling script use it to set configuration + +WebpackTemplateProvider: + dist: site/dist + hostname: localhost + port: "3000" + pages: site/src/js/types + src: site/src diff --git a/site/src/favicon.png b/site/src/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..966a2188068e4d7db1a65e4e2bc894bc942fb674 GIT binary patch literal 9255 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 J)W{*?{{SdYQ>p*} literal 0 HcmV?d00001 diff --git a/site/src/js/_components/_spinner.js b/site/src/js/_components/_spinner.js new file mode 100644 index 0000000..95c3042 --- /dev/null +++ b/site/src/js/_components/_spinner.js @@ -0,0 +1,19 @@ +/** + * Just an example component + */ +import $ from "jquery"; + +const SpinnerUI = (($) => { + class SpinnerUI { + static show(callback) { + $("#PageLoading").show(0, callback); + } + + static hide(callback) { + $("#PageLoading").hide("slow", callback); + } + } + return SpinnerUI; +})($); + +export default SpinnerUI; \ No newline at end of file diff --git a/site/src/js/_events.js b/site/src/js/_events.js new file mode 100644 index 0000000..7f0c0ab --- /dev/null +++ b/site/src/js/_events.js @@ -0,0 +1,8 @@ +/** + * Add your global events here + */ + +module.exports = { + AJAX: "ajax-load", + LOADED: "load" +}; \ No newline at end of file diff --git a/site/src/js/_pageType_and_component_template.js b/site/src/js/_pageType_and_component_template.js new file mode 100644 index 0000000..d2bc62b --- /dev/null +++ b/site/src/js/_pageType_and_component_template.js @@ -0,0 +1,88 @@ +import $ from "jquery"; + +const TypePage = (($) => { + + // Constants + const NAME = "TypePage"; + //const DATA_KEY = "pageUI." + NAME; + + const Events = require("./_events"); + + class TypePage { + // Static methods + static init() { + console.log("Initializing: " + NAME); + } + + static destroy() { + console.log("Destroying: " + NAME); + } + + /** + * jQuery extension functions + // Constructor + constructor(element) { + console.log("Constructing: " + NAME + " elements"); + + this._element = element; + } + + // Public methods + dispose() { + console.log("Disposing: " + NAME + " elements"); + + $.removeData(this._element, DATA_KEY); + this._element = null; + } + + static _jQueryInterface() { + return this.each(function () { + // attach functionality to element + const $element = $(this); + let data = $element.data(DATA_KEY); + + if (!data) { + data = new TypePage(this); + $element.data(DATA_KEY, data); + } + }) + } + */ + } + + $(window).on(Events.AJAX + " " + Events.LOADED, function() { + TypePage.init(); + }); + + // JQuery extension functions + /*$.fn[NAME] = TypePage._jQueryInterface; + $.fn[NAME].Constructor = TypePage; + $.fn[NAME].noConflict = function () { + $.fn[NAME] = JQUERY_NO_CONFLICT; + return TypePage._jQueryInterface; + };*/ + + return TypePage; +})($); + +export default TypePage; + + +/* +import $ from 'jquery'; + +(function (G) { + G.initPulsePage = function () { + G.destroyPulsePage(); + }; + + G.destroyPulsePage = function () {}; + + $(window).on("ajax-content-loaded", function () { + G.initPulsePage(); + }); + + $(document).ready(function () { + G.initPulsePage(); + }); +}(this));*/ \ No newline at end of file diff --git a/site/src/js/app.js b/site/src/js/app.js new file mode 100644 index 0000000..2a20a9a --- /dev/null +++ b/site/src/js/app.js @@ -0,0 +1,38 @@ +// import images +function importAll(r) { + return r.keys().map(r); +} + +const images = importAll(require.context("../img/", false, /\.(png|jpe?g|svg)$/)); + +import "../scss/app.scss"; + +// import Bootstrap +import Popper from "popper.js"; +window.Popper = Popper; +import "bootstrap/js/dist/util"; +import "bootstrap/js/dist/alert"; +import "bootstrap/js/dist/button"; +import "bootstrap/js/dist/carousel"; +import "bootstrap/js/dist/collapse"; +import "bootstrap/js/dist/dropdown"; +import "bootstrap/js/dist/modal"; +import "bootstrap/js/dist/tooltip"; +import "bootstrap/js/dist/popover"; +import "bootstrap/js/dist/scrollspy"; +import "bootstrap/js/dist/tab"; +// + +// import your custom UI components +import "./main.js"; + +// TODO: hot module update +/*const Events = require("./_events"); +if (module.hot) { + module.hot.accept(); + module.hot.addStatusHandler(status => { + if(status === "apply"){ + $(window).trigger(Events.AJAX); + } + }); +}*/ \ No newline at end of file diff --git a/site/src/js/main.js b/site/src/js/main.js new file mode 100644 index 0000000..a0cdb55 --- /dev/null +++ b/site/src/js/main.js @@ -0,0 +1,38 @@ +import $ from "jquery"; + +import Events from "./_events"; +// import an example component +import Spinner from "./_components/_spinner"; + +const MainUI = (($) => { + + // Constants + const NAME = "MainUI"; + + class MainUI { + // Static methods + static init() { + this.destroy(); + console.log("Initializing: " + NAME); + + Spinner.hide(function() { + $("body").addClass("loaded"); + }); + } + + static destroy() { + console.log("Destroying: " + NAME); + Spinner.show(function() { + $("body").removeClass("loaded"); + }); + } + } + + $(window).on(Events.AJAX + " " + Events.LOADED, function() { + MainUI.init(); + }); + + return MainUI; +})($); + +export default MainUI; \ No newline at end of file diff --git a/site/src/scss/_layout.scss b/site/src/scss/_layout.scss new file mode 100644 index 0000000..5ca54d0 --- /dev/null +++ b/site/src/scss/_layout.scss @@ -0,0 +1,7 @@ +/** + * Your custom style + */ + +html,body { + background:#000; +} \ No newline at end of file diff --git a/site/src/scss/_variables.scss b/site/src/scss/_variables.scss new file mode 100644 index 0000000..48a987c --- /dev/null +++ b/site/src/scss/_variables.scss @@ -0,0 +1,10 @@ +/* + * Your custom variables + */ + +// bootstrap minify bugfix: +$navbar-dark-toggler-icon-bg: none; +$navbar-light-toggler-icon-bg: none; + +// IE > 9 +$enable-flex: true; \ No newline at end of file diff --git a/site/src/scss/app.scss b/site/src/scss/app.scss new file mode 100644 index 0000000..c2eda41 --- /dev/null +++ b/site/src/scss/app.scss @@ -0,0 +1,42 @@ +// Your custom variables +@import "variables"; + +// Bootstrap basics +@import "../../../node_modules/bootstrap/scss/functions"; +@import "../../../node_modules/bootstrap/scss/variables"; +@import "../../../node_modules/bootstrap/scss/mixins"; +@import "../../../node_modules/bootstrap/scss/root"; +@import "../../../node_modules/bootstrap/scss/reboot"; +@import "../../../node_modules/bootstrap/scss/type"; +@import "../../../node_modules/bootstrap/scss/images"; +@import "../../../node_modules/bootstrap/scss/code"; +@import "../../../node_modules/bootstrap/scss/grid"; +@import "../../../node_modules/bootstrap/scss/tables"; +@import "../../../node_modules/bootstrap/scss/forms"; +@import "../../../node_modules/bootstrap/scss/buttons"; +@import "../../../node_modules/bootstrap/scss/transitions"; +@import "../../../node_modules/bootstrap/scss/dropdown"; +@import "../../../node_modules/bootstrap/scss/button-group"; +@import "../../../node_modules/bootstrap/scss/input-group"; +@import "../../../node_modules/bootstrap/scss/custom-forms"; +@import "../../../node_modules/bootstrap/scss/nav"; +@import "../../../node_modules/bootstrap/scss/navbar"; +@import "../../../node_modules/bootstrap/scss/card"; +@import "../../../node_modules/bootstrap/scss/breadcrumb"; +@import "../../../node_modules/bootstrap/scss/pagination"; +@import "../../../node_modules/bootstrap/scss/badge"; +@import "../../../node_modules/bootstrap/scss/jumbotron"; +@import "../../../node_modules/bootstrap/scss/alert"; +@import "../../../node_modules/bootstrap/scss/progress"; +@import "../../../node_modules/bootstrap/scss/media"; +@import "../../../node_modules/bootstrap/scss/list-group"; +@import "../../../node_modules/bootstrap/scss/close"; +@import "../../../node_modules/bootstrap/scss/modal"; +@import "../../../node_modules/bootstrap/scss/tooltip"; +@import "../../../node_modules/bootstrap/scss/popover"; +@import "../../../node_modules/bootstrap/scss/carousel"; +@import "../../../node_modules/bootstrap/scss/utilities"; +@import "../../../node_modules/bootstrap/scss/print"; + +// Your custom UI +@import "layout"; \ No newline at end of file diff --git a/site/templates/Page.ss b/site/templates/Page.ss new file mode 100644 index 0000000..23012d1 --- /dev/null +++ b/site/templates/Page.ss @@ -0,0 +1,64 @@ + + +<%-- manifest="/cache.appcache" --%> + + $MetaTags + + + + + + + + + + + + + + + + + + + + + <% base_tag %> + + + + + + + + + + + + + + + + + +
+ +
+ +
+ $Layout +
+ +
+ +
+ +
+ $BetterNavigator +
+ + $WebpackJS('app.js') + $WebpackCSS('app.css') + + + \ No newline at end of file diff --git a/webpack.config.common.js b/webpack.config.common.js new file mode 100755 index 0000000..edbacf8 --- /dev/null +++ b/webpack.config.common.js @@ -0,0 +1,122 @@ +const path = require("path"); +const webpack = require("webpack"); +const ExtractTextPlugin = require("extract-text-webpack-plugin"); +const ManifestPlugin = require("webpack-manifest-plugin"); +const conf = require("./webpack.configuration"); +const isProduction = process.env.NODE_ENV === "production"; + +const jsScripts = { + app: path.join(conf.SRC, "js/app.js"), +}; + +const _getAllFilesFromFolder = function(dir) { + let filesystem = require("fs"); + let results = []; + + filesystem.readdirSync(dir).forEach(function(file) { + + file = dir + "/" + file; + let stat = filesystem.statSync(file); + + if (stat && stat.isDirectory()) { + results = results.concat(_getAllFilesFromFolder(file)) + } else results.push(file); + + }); + + return results; +}; + +// add page specific scripts +const pageScripts = _getAllFilesFromFolder(conf.PAGES); +pageScripts.forEach((file) => { + jsScripts[path.basename(file, ".js")] = file; +}); + +module.exports = { + entry: jsScripts, + devtool: "source-map", + externals: { + "custom-select": "CustomSelect", + "ui-progress-button": "UIProgressButton" + }, + module: { + rules: [{ + test: /\.jsx?$/, + exclude: /node_modules/, + use: { + loader: "babel-loader", + options: { + presets: [ + ["es2015", { + modules: false + }], + ["stage-2"] + ], + plugins: [ + ["transform-react-jsx"], + ["react-hot-loader/babel"], + ] + }, + } + }, { + test: /\.(png|jpg|gif|svg)$/, + loader: "file-loader", + options: { + name: "img/[name].[ext]", + } + }, { + test: /\.eot(\?v=\d+.\d+.\d+)?$/, + use: { + loader: "file-loader", + options: { + name: "fonts/[name].[ext]" + } + } + }, { + test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, + use: { + loader: "url-loader", + options: { + name: "fonts/[name].[ext]", + limit: 10000, + mimetype: "application/font-woff" + } + } + }, { + test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/, + use: { + loader: "url-loader", + options: { + name: "fonts/[name].[ext]", + limit: 10000, + mimetype: "application/octet-stream" + } + } + }, { + test: /\.worker\.js$/, + use: { + loader: "worker-loader" + } + }] + }, + plugins: [ + new webpack.ProvidePlugin({ + $: "jquery", + jQuery: "jquery", + "window.jQuery": "jquery", + Popper: ["popper.js", "default"], + Util: "exports-loader?Util!bootstrap/js/dist/util", + Alert: "exports-loader?Alert!bootstrap/js/dist/alert", + Button: "exports-loader?Button!bootstrap/js/dist/button", + Carousel: "exports-loader?Carousel!bootstrap/js/dist/carousel", + Collapse: "exports-loader?Collapse!bootstrap/js/dist/collapse", + Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown", + Modal: "exports-loader?Modal!bootstrap/js/dist/modal", + Tooltip: "exports-loader?Tooltip!bootstrap/js/dist/tooltip", + Popover: "exports-loader?Popover!bootstrap/js/dist/popover", + Scrollspy: "exports-loader?Scrollspy!bootstrap/js/dist/scrollspy", + Tab: "exports-loader?Tab!bootstrap/js/dist/tab", + }) + ], +}; \ No newline at end of file diff --git a/webpack.config.dev.js b/webpack.config.dev.js new file mode 100755 index 0000000..559a12d --- /dev/null +++ b/webpack.config.dev.js @@ -0,0 +1,97 @@ +const autoprefixer = require('autoprefixer'); +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const common = require('./webpack.config.common.js'); +const conf = require('./webpack.configuration'); + +const IP = process.env.IP || conf.HOSTNAME; +const PORT = process.env.PORT || conf.PORT; + +const config = merge.strategy({ + entry: 'prepend' +})(common, { + + entry: { + app: [ + 'react-hot-loader/patch', + 'webpack-dev-server/client?http://' + conf.HOSTNAME + ':' + conf.PORT + '/', + 'webpack/hot/only-dev-server', + ], + main: [ + 'webpack-dev-server/client?http://' + conf.HOSTNAME + ':' + conf.PORT + '/', + 'webpack/hot/only-dev-server', + ], + }, + + output: { + path: conf.BUILD, + filename: '[name].js', + // necessary for HMR to know where to load the hot update chunks + publicPath: 'http://' + conf.HOSTNAME + ':' + conf.PORT + '/' + }, + + module: { + rules: [{ + test: /\.scss$/, + use: [{ + loader: 'style-loader', + options: { + sourceMap: true + } + }, { + loader: 'css-loader', + options: { + sourceMap: true + } + }, { + loader: 'postcss-loader', + options: { + sourceMap: true, + plugins: [ + autoprefixer({ + // If we want to use the same browser list for more tools + // this list should be moved to package.json + // https://evilmartians.com/chronicles/autoprefixer-7-browserslist-2-released + browsers: [ + 'ie >= 11', + 'ie_mob >= 11', + 'Safari >= 10', + 'Android >= 4.4', + 'Chrome >= 44', // Retail + 'Samsung >= 4' + ] + }), + // http://lostgrid.org/docs.html + require('lost') + ] + } + }, { + loader: 'sass-loader', + options: { + sourceMap: true + } + }, ] + }, ] + }, + plugins: [ + new webpack.NamedModulesPlugin(), + new webpack.HotModuleReplacementPlugin(), + new webpack.NoEmitOnErrorsPlugin(), + ], + + devServer: { + host: IP, + port: PORT, + historyApiFallback: true, + hot: true, + overlay: { + warnings: true, + errors: true + }, + headers: { + 'Access-Control-Allow-Origin': '*' + } + }, +}); + +module.exports = config; \ No newline at end of file diff --git a/webpack.config.prod.js b/webpack.config.prod.js new file mode 100755 index 0000000..cedee69 --- /dev/null +++ b/webpack.config.prod.js @@ -0,0 +1,102 @@ +const path = require('path'); +const autoprefixer = require('autoprefixer'); +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const common = require('./webpack.config.common.js'); +const OptimizeCSSAssets = require('optimize-css-assets-webpack-plugin'); +const conf = require('./webpack.configuration'); +const ExtractTextPlugin = require("extract-text-webpack-plugin"); +const FaviconsWebpackPlugin = require("favicons-webpack-plugin"); +const fs = require("fs"); +const yaml = require("js-yaml"); +const confYML = yaml.safeLoad(fs.readFileSync(path.join(__dirname, "site/_config/webpack.yml"), "utf8")); + +module.exports = merge(common, { + + output: { + path: conf.BUILD, + filename: '[name].js', + publicPath: confYML.WebpackTemplateProvider.dist + '/', + }, + + module: { + rules: [{ + test: /\.scss$/, + use: ExtractTextPlugin.extract({ + fallback: "style-loader", + use: [{ + loader: 'css-loader', + options: { + sourceMap: true + } + }, { + loader: 'postcss-loader', + options: { + sourceMap: true, + plugins: [ + autoprefixer({ + // If we want to use the same browser list for more tools + // this list should be moved to package.json + // https://evilmartians.com/chronicles/autoprefixer-7-browserslist-2-released + browsers: [ + 'ie >= 11', + 'ie_mob >= 11', + 'Safari >= 10', + 'Android >= 4.4', + 'Chrome >= 44', // Retail + 'Samsung >= 4' + ] + }), + // http://lostgrid.org/docs.html + require('lost') + ] + } + }, { + loader: 'resolve-url-loader' + }, { + loader: 'sass-loader', + options: { + sourceMap: true + } + }, ] + }) + }, ] + }, + + plugins: [ + + new webpack.DefinePlugin({ + 'process.env': { + 'NODE_ENV': JSON.stringify('production') + } + }), + + new webpack.optimize.ModuleConcatenationPlugin(), + new webpack.optimize.UglifyJsPlugin({ + sourceMap: true, + comments: false + }), + new ExtractTextPlugin({ + filename: '[name].css', + allChunks: true + }), + new OptimizeCSSAssets(), + new FaviconsWebpackPlugin({ + logo: conf.SRC + '/favicon.png', + prefix: '/icons/', + statsFilename: confYML.WebpackTemplateProvider.dist + '/icons/iconstats.json', + icons: { + android: true, + appleIcon: true, + appleStartup: true, + coast: true, + favicons: true, + firefox: true, + opengraph: true, + twitter: true, + yandex: true, + windows: true + } + }), + ], +}); \ No newline at end of file diff --git a/webpack.configuration.js b/webpack.configuration.js new file mode 100755 index 0000000..6921736 --- /dev/null +++ b/webpack.configuration.js @@ -0,0 +1,12 @@ +const path = require("path"); +const fs = require("fs"); +const yaml = require("js-yaml"); +const conf = yaml.safeLoad(fs.readFileSync(path.join(__dirname, "site/_config/webpack.yml"), "utf8")); + +module.exports = { + SRC: path.join(__dirname, conf.WebpackTemplateProvider.src), + BUILD: path.join(__dirname, conf.WebpackTemplateProvider.dist), + PAGES: path.join(__dirname, conf.WebpackTemplateProvider.pages), + HOSTNAME: conf.WebpackTemplateProvider.hostname, + PORT: conf.WebpackTemplateProvider.port +}; \ No newline at end of file