diff --git a/.browserslistrc b/.browserslistrc index 128e4dd647..e94f8140cc 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -1,4 +1 @@ -last 2 versions -not dead -> 1% in US -ie 11 +defaults diff --git a/.eslintrc.js b/.eslintrc.js index 1ca20a2910..5b779e7fa8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,19 +6,12 @@ */ module.exports = { - extends: [ - 'airbnb-base', - 'plugin:jest/recommended', - 'plugin:vue/recommended', - 'plugin:prettier/recommended', - 'prettier/vue', - ], - plugins: ['prettier'], + extends: ['airbnb-base', 'plugin:jest/recommended', 'prettier'], root: true, globals: { Drupal: true, jQuery: true, - _: true, + // _: true, BUILD_TARGET: true, }, env: { @@ -27,6 +20,7 @@ module.exports = { }, rules: { 'no-console': [0], // turned off for now while we are console.logging everywhere. + // @TODO: return to this vv 'import/no-extraneous-dependencies': ['error', { devDependencies: true }], }, }; diff --git a/.huskyrc b/.huskyrc index bf229fdba3..196b2d1ffc 100644 --- a/.huskyrc +++ b/.huskyrc @@ -1,2 +1,2 @@ hooks: - pre-commit: "pretty-quick --staged" + pre-commit: "pretty-quick --staged && npm run lint && npm test" diff --git a/.prettierrc.js b/.prettierrc.js index 002c7d762d..4f0abdee16 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,8 +1,4 @@ module.exports = { - plugins: ['./node_modules/prettier-plugin-twig-melody'], proseWrap: 'always', singleQuote: true, - twigAlwaysBreakObjects: true, - twigOutputEndblockName: true, - twigPrintWidth: 120, }; diff --git a/.travis.yml b/.travis.yml index 5c22a99fb8..fa48c92976 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,9 @@ php: - 7.2 env: matrix: - - TRAVIS_NODE_VERSION="8" - TRAVIS_NODE_VERSION="10" - TRAVIS_NODE_VERSION="12" + - TRAVIS_NODE_VERSION="14" before_install: - '. $HOME/.nvm/nvm.sh' - nvm install $TRAVIS_NODE_VERSION @@ -23,7 +23,7 @@ before_script: - node --version - npm --version script: - - npm run ci + - npm run verify notifications: email: on_success: always diff --git a/apps/drupal-default/particle.app.config.js b/apps/drupal-default/particle.app.config.js deleted file mode 100644 index 4ae6d24c53..0000000000 --- a/apps/drupal-default/particle.app.config.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Particle app conventions - */ - -const path = require('path'); - -const { - DRUPAL_DIST, - ASSETS_BUNDLE_FOLDER, -} = require('../../particle.root.config'); - -// Used as folder name within PATH_DIST, does not have to be folder name of app -const APP_NAME = 'app-drupal'; -// Full path to app -const APP_PATH = path.resolve(__dirname); -// Full path to design system used in this app -const APP_DESIGN_SYSTEM = path.resolve(__dirname, '../../source/default'); -// Where should this app compile to, e.g. dist/app-drupal/assets/ -const APP_DIST = path.join(DRUPAL_DIST, APP_NAME, ASSETS_BUNDLE_FOLDER); -// Base path for all assets -const APP_DIST_PUBLIC = path.join(APP_NAME, ASSETS_BUNDLE_FOLDER); - -module.exports = { - APP_NAME, - APP_PATH, - APP_DESIGN_SYSTEM, - APP_DIST, - APP_DIST_PUBLIC, -}; diff --git a/apps/drupal-default/particle_theme/particle.info.yml b/apps/drupal-default/particle_theme/particle.info.yml index 9379e2067a..c9391a85f0 100644 --- a/apps/drupal-default/particle_theme/particle.info.yml +++ b/apps/drupal-default/particle_theme/particle.info.yml @@ -27,13 +27,13 @@ component-libraries: paths: [] atoms: paths: - - ../../../dist/app-drupal/assets/atomic/_patterns/01-atoms + - dist/atomic/_patterns/01-atoms molecules: paths: - - ../../../dist/app-drupal/assets/atomic/_patterns/02-molecules + - dist/atomic/_patterns/02-molecules organisms: paths: - - ../../../dist/app-drupal/assets/atomic/_patterns/03-organisms + - dist/atomic/_patterns/03-organisms templates: paths: [] pages: diff --git a/apps/drupal-default/particle_theme/particle.libraries.yml b/apps/drupal-default/particle_theme/particle.libraries.yml index 0fa836c203..b8cdfed2ca 100644 --- a/apps/drupal-default/particle_theme/particle.libraries.yml +++ b/apps/drupal-default/particle_theme/particle.libraries.yml @@ -4,10 +4,10 @@ core: css: theme: - ../../../dist/app-drupal/assets/app.styles.css: + dist/app.css: minified: true js: - ../../../dist/app-drupal/assets/app.js: + dist/app.js: preprocess: false # See all in Drupal's `core/core.libraries.yml` dependencies: @@ -18,6 +18,6 @@ core: # See `libraries-override` in particle.info.yml jquery: js: - ../../../dist/app-drupal/assets/drupal-jquery.js: + dist/drupal-jquery.js: preprocess: false weight: -20 diff --git a/apps/drupal-default/webpack.config.js b/apps/drupal-default/webpack.config.js index 21d64ca936..86aa5aaf55 100644 --- a/apps/drupal-default/webpack.config.js +++ b/apps/drupal-default/webpack.config.js @@ -3,31 +3,23 @@ */ const path = require('path'); -const { DefinePlugin } = require('webpack'); - -// Plugins -const RunScriptAfterEmit = require('../../tools/webpack/run-script-after-emit'); -const particle = require('../../particle'); -// Constants: environment -const { NODE_ENV } = process.env; - -// Constants: root -const { ASSETS_ATOMIC_FOLDER } = require('../../particle.root.config'); +const { DefinePlugin } = require('webpack'); +const { merge } = require('webpack-merge'); -// Constants: app -const appConfig = require('./particle.app.config'); +// Get design system config +const dsWebpackConfig = require('../../source/default/webpack.config'); -const { APP_NAME, APP_DESIGN_SYSTEM, APP_DIST, APP_DIST_PUBLIC } = appConfig; +const APP_NAME = 'app-drupal'; -const shared = { +const drupalWebpackConfig = { entry: { 'drupal-jquery': [path.resolve(__dirname, 'drupal-jquery.js')], app: [path.resolve(__dirname, 'index.js')], }, output: { - path: APP_DIST, - publicPath: APP_DIST_PUBLIC, + // Output all CSS/JS/images/twig to dist/ within drupal theme + path: path.resolve(__dirname, 'particle_theme/dist'), }, module: { rules: [ @@ -36,8 +28,8 @@ const shared = { loader: 'file-loader', options: { name: '[path][name].[ext]', - outputPath: ASSETS_ATOMIC_FOLDER, - context: APP_DESIGN_SYSTEM, + outputPath: 'atomic/', + context: path.resolve(__dirname, '../../source/default/'), emit: true, }, }, @@ -48,44 +40,13 @@ const shared = { BUILD_TARGET: JSON.stringify(APP_NAME), }), ], -}; - -const dev = { - stats: { - children: false, - entrypoints: false, - }, - plugins: [ - new RunScriptAfterEmit({ - exec: [ - // prettier-ignore - `echo \nšŸš€ Webpack Drupal ${NODE_ENV} build complete! Edit - apps/drupal-default/webpack.config.js to replace this line with - anything you'd like run after rebuilding assets, e.g. - 'drupal cr all'. šŸš€\n`, - ], - }), - ], externals: { jquery: 'jQuery', }, -}; - -const prod = { stats: { children: false, - entrypoints: false, chunks: false, }, }; -module.exports = particle( - // app: webpack - { shared, dev, prod }, - // app: config - appConfig, - // Use extract css - { - cssMode: 'extract', - } -); +module.exports = merge(dsWebpackConfig, drupalWebpackConfig); diff --git a/apps/pl-default/index.js b/apps/pl-default/index.js index 4c8d1c88c1..6d0c5f25f2 100644 --- a/apps/pl-default/index.js +++ b/apps/pl-default/index.js @@ -19,8 +19,6 @@ import 'prismjs/components/prism-css.min'; import 'prismjs/components/prism-scss.min'; import 'prismjs/components/prism-markup.min'; -// Local config -import { APP_NAME } from './particle.app.config'; // Full design system. May dupe the above, but Webpack don't care. import { enableAllComponents } from '../../source/default'; @@ -32,9 +30,8 @@ const $context = $(document); // Configure PL-specific settings here const settings = { - // card wants to know if it should enable holder.js. - // BUILD_TARGET is either 'pl' or 'drupal', and comes from webpack - enableHolder: BUILD_TARGET === APP_NAME, + // Enable SVG placeholder images for PL demos + enableHolder: true, // a random drupalSetting color: '#ce8500', }; diff --git a/apps/pl-default/particle.app.config.js b/apps/pl-default/particle.app.config.js deleted file mode 100644 index bdf135a23e..0000000000 --- a/apps/pl-default/particle.app.config.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Particle app conventions - */ - -const path = require('path'); - -const { - PATTERN_LAB_DIST, - ASSETS_BUNDLE_FOLDER, -} = require('../../particle.root.config'); - -// Used as folder name within PATH_DIST, does not have to be folder name of app -const APP_NAME = 'app-pl'; -// Full path to app -const APP_PATH = path.resolve(__dirname); -// Full path to design system used in this app -const APP_DESIGN_SYSTEM = path.resolve(__dirname, '../../source/default'); -// Where should this app compile to, e.g. dist/app-drupal/assets/ -const APP_DIST = path.join(PATTERN_LAB_DIST, APP_NAME, ASSETS_BUNDLE_FOLDER); -// Base path for all assets -const APP_DIST_PUBLIC = `/${path.join(APP_NAME, ASSETS_BUNDLE_FOLDER)}`; - -module.exports = { - APP_NAME, - APP_PATH, - APP_DESIGN_SYSTEM, - APP_DIST, - APP_DIST_PUBLIC, -}; diff --git a/apps/pl-default/pattern-lab/.gitignore b/apps/pl-default/pattern-lab/.gitignore deleted file mode 100644 index add2984707..0000000000 --- a/apps/pl-default/pattern-lab/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.DS_Store -export -packages -public diff --git a/apps/pl-default/pattern-lab/_meta/_00-head.mustache b/apps/pl-default/pattern-lab/_meta/_00-head.mustache index 408ef1c744..45ce3bb7d0 100644 --- a/apps/pl-default/pattern-lab/_meta/_00-head.mustache +++ b/apps/pl-default/pattern-lab/_meta/_00-head.mustache @@ -13,6 +13,5 @@ - - + diff --git a/apps/pl-default/pattern-lab/_meta/_00-head.twig b/apps/pl-default/pattern-lab/_meta/_00-head.twig index 8d8fb9f701..8bbe37265c 100644 --- a/apps/pl-default/pattern-lab/_meta/_00-head.twig +++ b/apps/pl-default/pattern-lab/_meta/_00-head.twig @@ -16,7 +16,7 @@ {% if env == 'production' %} - + {% endif %} diff --git a/source/default/lib/vue-widget/src/vue-cards/components/card.vue b/source/default/lib/vue-widget/src/vue-cards/components/card.vue deleted file mode 100644 index e8442b33bb..0000000000 --- a/source/default/lib/vue-widget/src/vue-cards/components/card.vue +++ /dev/null @@ -1,53 +0,0 @@ - - - diff --git a/source/default/lib/vue-widget/src/vue-cards/components/cards.vue b/source/default/lib/vue-widget/src/vue-cards/components/cards.vue deleted file mode 100644 index 454ca1e38c..0000000000 --- a/source/default/lib/vue-widget/src/vue-cards/components/cards.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - - - diff --git a/source/default/lib/vue-widget/src/vue-cards/index.js b/source/default/lib/vue-widget/src/vue-cards/index.js deleted file mode 100644 index 60ab4470ca..0000000000 --- a/source/default/lib/vue-widget/src/vue-cards/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import Vue from 'vue'; - -import App from './app.vue'; - -export default (el) => - new Vue({ - el, - render: (h) => h(App), - }); diff --git a/source/default/lib/vue-widget/src/vue-clock/index.js b/source/default/lib/vue-widget/src/vue-clock/index.js deleted file mode 100644 index f6f2066491..0000000000 --- a/source/default/lib/vue-widget/src/vue-clock/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import Vue from 'vue'; - -import Clock from './vue-clock.vue'; - -export default (el) => - new Vue({ - el, - render: (h) => h(Clock), - }); diff --git a/source/default/lib/vue-widget/src/vue-clock/vue-clock.vue b/source/default/lib/vue-widget/src/vue-clock/vue-clock.vue deleted file mode 100644 index 0bf1d536d1..0000000000 --- a/source/default/lib/vue-widget/src/vue-clock/vue-clock.vue +++ /dev/null @@ -1,116 +0,0 @@ - - - - - diff --git a/source/default/lib/vue-widget/store.js b/source/default/lib/vue-widget/store.js deleted file mode 100644 index c8981dcd11..0000000000 --- a/source/default/lib/vue-widget/store.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Vuex Store - */ - -import Vue from 'vue'; -import Vuex from 'vuex'; - -Vue.use(Vuex); - -/** - * STATE - */ -const state = {}; - -/** - * MUTATIONS - */ -const mutations = {}; - -/** - * ACTIONS - */ -const actions = {}; - -/** - * GETTERS - */ -const getters = {}; - -export default new Vuex.Store({ - state, - mutations, - actions, - getters, -}); diff --git a/source/default/tailwind.config.js b/source/default/tailwind.config.js index 6a5336e952..52fffb9bb6 100644 --- a/source/default/tailwind.config.js +++ b/source/default/tailwind.config.js @@ -19,23 +19,25 @@ module.exports = { content: [path.resolve(__dirname, '_patterns/**/*.*')], options: { // Whitelist Non-DS Dependent Patterns. - whitelistPatterns: [ - /^bg/, - /^text/, - /:?-?m[rltbxy]?-/, - /:?p[rltbxy]?-/, - /:?w-/, - ], + whitelistPatterns: [/^bg/, /^text/, /^w-/, /^h-/, /^js-/, /^form-/], defaultExtractor: (content) => content.match(/[A-Za-z0-9-_:/]+/g) || [], extensions: ['yml', 'twig', 'json', 'js', 'ts'], }, }, theme: { + // Replace default Tailwind config here colors, customForms, fontFamily, + // Extend (add to) default Tailwdind config here extend: {}, }, variants: {}, plugins: [tailwindCustomForms], + future: { + removeDeprecatedGapUtilities: true, + purgeLayersByDefault: true, + defaultLineHeights: true, + standardFontWeights: true, + }, }; diff --git a/source/default/webpack.config.js b/source/default/webpack.config.js index 3bf4911000..3b5458ab70 100644 --- a/source/default/webpack.config.js +++ b/source/default/webpack.config.js @@ -4,32 +4,14 @@ const path = require('path'); +const { merge } = require('webpack-merge'); const SVGSpritemapPlugin = require('svg-spritemap-webpack-plugin'); +const rootWebpackConfig = require('../../webpack.particle'); const namespaces = require('./namespaces'); -module.exports = { - module: { - rules: [ - { - test: /\.css$/, - use: [ - { - loader: 'postcss-loader', - options: { - config: { - path: path.join('postcss.config.js'), - ctx: { - // PostCSS Tailwind config - tailwindConfig: path.resolve(__dirname, 'tailwind.config.js'), - }, - }, - }, - }, - ], - }, - ], - }, +// Merge root Webpack config with design system Webpack config +module.exports = merge(rootWebpackConfig, { plugins: [ // Sprite system options new SVGSpritemapPlugin( @@ -50,6 +32,5 @@ module.exports = { // JavaScript can import other components via shorthand, eg: // `import thing from 'atoms/thing';` alias: namespaces, - extensions: ['.js', '.json'], }, -}; +}); diff --git a/spacing.json b/spacing.json deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/webpack/import-all.js b/tools/webpack/import-all.js index b2b11c647c..5094d4f6f1 100644 --- a/tools/webpack/import-all.js +++ b/tools/webpack/import-all.js @@ -2,12 +2,12 @@ * Accepts the result of require.context() to add it all to our great big * components object with keys that are the name of components, i.e. * - * // 01-atoms/vue-widget/index.js - * export const name = 'vue-widget'; + * // 01-atoms/button/index.js + * export const name = 'button'; * * results in: * - * components['vue-widget'] = {name: 'vue-widget', enable() {}, disable() {}} + * components['button'] = {name: 'button', enable() {}, disable() {}} * * @param context */ diff --git a/webpack.particle.js b/webpack.particle.js index 337fbefbbe..0621c8b6d9 100644 --- a/webpack.particle.js +++ b/webpack.particle.js @@ -9,8 +9,9 @@ const { ProgressPlugin, ProvidePlugin } = require('webpack'); // Plugins -const VueLoaderPlugin = require('vue-loader/lib/plugin'); const TerserPlugin = require('terser-webpack-plugin'); +const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const StylelintPlugin = require('stylelint-webpack-plugin'); // Constants: environment // NODE_ENV is set within all NPM scripts before running Webpack, eg: @@ -27,7 +28,6 @@ const { NODE_ENV = 'production' } = process.env; // process.traceDeprecation = true; module.exports = { - // entry: {}, // See entryPrepend() and particle() below for entry details mode: NODE_ENV, // development|production output: { filename: '[name].js', @@ -35,43 +35,17 @@ module.exports = { devtool: NODE_ENV === 'development' ? 'eval' : 'source-map', module: { rules: [ - { - test: /\.vue$/, - loader: 'vue-loader', - options: { - loaders: { - js: 'babel-loader', - }, - }, - }, { test: /\.css$/, use: [ - { - loader: 'css-loader', - options: { - sourceMap: true, - }, - }, - { - loader: 'resolve-url-loader', - options: { - sourceMap: true, - root: '', - }, - }, - { - // PostCSS config at ./postcss.config.js - loader: 'postcss-loader', - options: { - sourceMap: true, - ident: 'postcss', - }, - }, + MiniCssExtractPlugin.loader, + 'css-loader', + 'resolve-url-loader', + 'postcss-loader', ], }, { - test: /\.(js|vue)$/, + test: /\.js$/, enforce: 'pre', exclude: /node_modules/, loader: 'eslint-loader', @@ -84,9 +58,7 @@ module.exports = { test: /\.js$/, // @babel runtime and core must NOT be transformed by babel exclude: /@babel(?:\/|\\{1,2})runtime|core-js/, - use: { - loader: 'babel-loader', - }, + use: ['babel-loader'], }, { test: /\.(png|jpg|gif|svg)$/, @@ -124,6 +96,10 @@ module.exports = { ], }, plugins: [ + // Throw stylelint warnings and errors to console + new StylelintPlugin(), + // Write CSS to disk + new MiniCssExtractPlugin(), // Provides "global" vars mapped to an actual dependency. Allows e.g. jQuery // plugins to assume that `window.jquery` is available new ProvidePlugin({ @@ -131,20 +107,12 @@ module.exports = { jQuery: 'jquery', 'window.jQuery': 'jquery', }), - // Handle .vue files - new VueLoaderPlugin(), + // Only add ProgressPlugin for non-production env. ...(NODE_ENV === 'production' ? [] : [new ProgressPlugin({ profile: false })]), ], - resolve: { - alias: { - // Since we operate in a world where random Vue templates might have to - // be output via twig, we need the Vue build that includes the whole - // template compiling engine. If we are on a build that will NEVER read - // HTML from the DOM and use it as a template, then remove this line. - vue$: 'vue/dist/vue.esm.js', - }, - }, + // All stats available here: https://webpack.js.org/configuration/stats/ + // stats: {}, };