Giter VIP home page Giter VIP logo

vue-skeleton's People

Contributors

gianko avatar hjeti avatar jesse-mm avatar mediamonks-stuart avatar renedrie avatar riccoarntz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-skeleton's Issues

Don't output webpack generated assets in a version number folder

We are already using hash filenaming for some assets. Which is great, because this optimizes caching: changed files get a different filename but assets that have not changed will still have the same path so they are cached by the browser. However, by putting assets in a /version/xxxx folder the path will change on every build, regardless of the contents of the asset has changed. This makes the hash in the filename redundant.

Use webpack to load locale modules

Currently we are loading locale files by putting jsons in the static folder and using a localeLoader function to load them from there. There is no reason these files can't be imported through webpack. This gives us all advantages of webpack bundling like using hash filenames for the locale files.

Generally speaking, we should not have any files in the static folder. The static folder should only be used for assets that are impossible or impractical to go through webpack.

In my current project, the jsons are placed in src/locale/ and the getTranslation function in bootstrap.js looks like so:

function getTranslation({code}) {
  return import('./locale/' + code.toLowerCase() + '.json');
}

I noticed we also have a custom function that waits until the locales have loaded. Is there any reason not to use the Vue.initI18nManager function provided by vue-i18n-manager? See the note at the bottom of the getting started page.

Can and should we update to ES7?

Currently the target in the tslint is set to ES6. And for instance when you do in Typescript:
[1,2,3].includes(value => value === 1)
It will throw an arrow that it can't find the method includes on an Array. There is more about this in this issue:
microsoft/TypeScript#2340

Setting it to ES7/es2017 fixes this. But I'm not sure if there are other implications or stuff that might be going wrong then?

If that is the case, we can leave it like this.

worker-loader compatibility

Currently there are two issues when using web workers related code in the Vue Skeleton:

  1. "allowJs": true, in the tsconfig.json will make TS try to understand webworkers that are going through webpack and being changed, but TS will fail and say it's not a module (which it indeed isn't).
  2. Hot Reloading config will add a window reference in the webpack header of the worker file, which breaks in a web worker.

Current workarounds:

  1. Add a // @ts-ignore comment above the worker imports
  2. Add globalObject: 'this', to the output section of the webpack config.

For point 1 we cannot do much I think, people should just remember to do that.
For point 2 we could make an update to the skeleton to set it as a default.

Add 'name' to routes

Should we add a name by default to the routes? This makes it simple to use the (localised) router-link.

Build doesn't exit with error after failed webpack

if (err) throw err;

This line only throws when there is an actual JS error.

Below you can see errors that are webpack build errors (that don't throw), that are available in the stats object.

To have this properly work, we need to check the stats object for any errors, and throw an error after logging it.

�[1m�[31mERROR in ./node_modules/extract-text-webpack-plugin/dist/loader.js?{"omit":1,"remove":true}!./node_modules/vue-style-loader!./node_modules/css-loader?{"localIdentName":"[local]-[hash:base64:7]","importLoaders":true,"camelCase":true,"modules":true}!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-01964e59","scoped":false,"hasInlineConfig":true}!./node_modules/sass-loader/lib/loader.js?{"data":"@import /"src/asset/style/utils.scss/";","includePaths":["src/asset/style"]}!./src/App/App.scss
Module build failed: ModuleBuildError: Module build failed: Error: Missing binding source/frontend/node_modules/node-sass/vendor/linux-x64-57/binding.node
Node Sass could not find a binding for your current environment: Linux 64-bit with Node.js 8.x

Found bindings for the following environments:
  - Linux 64-bit with Node.js 6.x

This usually happens because your environment has changed since running `npm install`.
Run `npm rebuild node-sass --force` to build the binding for your current environment.
    at module.exports (source/frontend/node_modules/node-sass/lib/binding.js:15:13)
    at Object. (source/frontend/node_modules/node-sass/lib/index.js:14:35)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Module.require (module.js:587:17)
    at require (internal/module.js:11:18)
    at Object. (source/frontend/node_modules/sass-loader/lib/loader.js:3:14)
    at Module._compile (module.js:643:30)
    at Object.Module._extensions..js (module.js:654:10)
    at Module.load (module.js:556:32)
    at tryModuleLoad (module.js:499:12)
    at Function.Module._load (module.js:491:3)
    at Module.require (module.js:587:17)
    at runLoaders (source/frontend/node_modules/webpack/lib/NormalModule.js:195:19)
    at source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:364:11
    at source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:170:18
    at loadLoader (source/frontend/node_modules/loader-runner/lib/loadLoader.js:27:11)
    at iteratePitchingLoaders (source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:169:2)
    at iteratePitchingLoaders (source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:165:10)
    at source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:173:18
    at loadLoader (source/frontend/node_modules/loader-runner/lib/loadLoader.js:36:3)
    at iteratePitchingLoaders (source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:169:2)
    at iteratePitchingLoaders (source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:165:10)
    at source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:173:18
    at loadLoader (source/frontend/node_modules/loader-runner/lib/loadLoader.js:36:3)
    at iteratePitchingLoaders (source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:169:2)
    at runLoaders (source/frontend/node_modules/loader-runner/lib/LoaderRunner.js:362:2)
    at NormalModule.doBuild (source/frontend/node_modules/webpack/lib/NormalModule.js:182:3)
    at NormalModule.build (source/frontend/node_modules/webpack/lib/NormalModule.js:275:15)
 @ ./node_modules/extract-text-webpack-plugin/dist/loader.js?{"omit":1,"remove":true}!./node_modules/vue-style-loader!./node_modules/css-loader?{"localIdentName":"[local]-[hash:base64:7]","importLoaders":true,"camelCase":true,"modules":true}!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-01964e59","scoped":false,"hasInlineConfig":true}!./node_modules/sass-loader/lib/loader.js?{"data":"@import /"src/asset/style/utils.scss/";","includePaths":["src/asset/style"]}!./src/App/App.scss
 @ ./src/App/App.vue
 @ ./src/App/index.js
 @ ./src/bootstrap.js�[39m�[22m

You can preview your build by running: yarn preview
You can analyze your build by running: yarn analyze

Webpack Bundle Analyzer saved stats file to source/frontend/stats.json

source/frontend> cp -pr dist/* $DEPLOY_PATH/web/
Exit code: 0 (141475ms)

Suggestion: improve use of store constants

I think the latest change in the mutations/actions/getter constants has been very good (getting rid of the namespace), but i still think it can be improved upon. I have three suggestions, which is basically the system i have been using for quite a while and which not everyone seems to like, but i think we should at least implement the first one.

1. combine them into an object per store
Each constant is now exported separately, which seems a bit weird since we don't do that anywhere else (it would be like exporting each RouteName entry separately). But more practically, if i have a bunch of stores with each a bunch of mutations (SET_USERNAME, SET_SCORE), whenever i want to auto-fill/import something by typing "SET_", i get a very big list of entries to choose from, and it will be not clear to what store they belong and what they do (since the constant typically doesn't contain the store name).

I think exporting those constants like this would be more practical:

export const appStore = {
    SET_DEVICE_STATE: `${namespace}/setDeviceState`,
}

In my opinion this is a lot easier to use. You just type that storename somewhere, autoimport it and the autocomplete lets you explore whatever values it has on it.

2. categorize constants per store
I would go even further and group those values, since it's not always clear what a specific constant is (especially mutations and actions, their names can sometimes be a bit similar - although i think these two will be merged by vuex somewhere in the future).

export const appStore = {
    mutation: {
        SET_DEVICE_STATE: `${namespace}/setDeviceState`,
    },
    action: {
        LOGIN: `${namespace}/login`,
    }
}

I think using this in a component will make it very readable as well:

...mapActions({
    login: userStore.action.LOGIN,
});

3. automatically fill those values
Regardless of whether we add the 2nd suggestion, i personally don't see why you wouldn't want to automatically set all those values instead of duplicating things, although this approach wasn't universally liked :)

export const appStore = initStoreConstants({
    mutation: {
        SET_DEVICE_STATE: null,
        SET_USERNAME: null,
    },
}, namespace);

(instead of the null values, this could also be done by what seng-event does with EVENT_TYPE_PLACEHOLDER)

Let me know what you think. Like i said, i think we should at least implement the first one to avoid the big list of options whenever you start typing SET_

Errors in dev server are sometimes not displayed

In some cases, the dev server console will simply say "Failed to compile with errors" without actually listing the errors. This is not very helpful. I suspect it is due to FriendlyErrorsWebpackPlugin. If I remove it and disable the quiet option in the devServer config, the errors show up again.

CSS global class compilation order

Hi HJ! ✨✨

I'm using global CSS classes to reuse styles in elements for example,

.overlay {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 1;
}

The problem arises when I want to step on some of the rules since in dev the compilation order of the css is different than in production

screen shot 2018-06-28 at 15 58 04

Dev

screen shot 2018-06-28 at 15 18 54

Prod (I put !important for it to work)

screen shot 2018-06-28 at 15 20 05

Is there a way for the compilation order to be the same in dev as prod?

Besis! ❤️ 💋 💋 💋

LodashModuleReplacementPlugin breaks Lodash functions in production build

Currently when using one of the following Lodash functions: get, has or set in your project they break when running a production build. This is due to the webpack LodashModuleReplacementPlugin, which has a flag for allowing those methods, https://github.com/lodash/lodash-webpack-plugin.

Adding this to thewebpack.prod.conf.js file should allow you to use those methods in your project!

new LodashModuleReplacementPlugin({
  paths: true,
}),

Rename Pages.js?

The name Pages is not really descriptive...if i had to guess, it would be what PageNames is now: just some names to refer to a page, regardless of any context.

Instead, Pages holds values that are used in a very specific way: they are the paths to the pages. My suggestion would be to rename it to PagePaths

Device state tracker implementation with multiple queries

Something you want to use a mediaQuery with more than 1 condition like:
"(min-width: 768px) and (orientation: landscape)"

The SCSS importer doesn't understand this so you have to add extra quotes around it:
"'(min-width: 768px) and (orientation: landscape)'"

Unfortunately the DeviceStateTracker doesn't understand this anymore, so we could add a replace regex in the DeviceStateTracker, or parse the JSON with the replace in the startUp.
So something like:
`const cleanQueries = {};
Object.keys(mediaQueries).forEach(key => {
cleanQueries[key] = mediaQueries[key].replace(/'/g, '');
});

new DeviceStateTracker({
mediaQueries: cleanQueries,
deviceState,
showStateIndicator: process.env.NODE_ENV !== 'production',
})`

Problems with updating to more recent Node, package versions; `gulp-util` usage

Node 10 came out about a week ago.

Attempting to use Node10 in the vue-skeleton triggers an error with the upath node module: the version used by this project is not configured correctly to recognize Node10 as a valid version, and thus fails any attempt to, for example, build & run the local dev server.

Running yarn upgrade after having upgraded to Node10 fixes this (obviously), but also outputs a warning about gulp-util, with this Medium post linked.

Should this be taken care of in this project, or be left up to whoever builds their own project off of this one?

Keep search query parameters upon navigation

Most of the time the search query parameters are used for tracking stuff (GTM). But upon navigating without a Vue app those parameters are removed.
This causes issues with the tracking instances and we might not want that.

There is a solution with a beforeEach hook:
https://stackoverflow.com/questions/42226479/how-to-hold-url-query-params-in-vue-with-vue-router

We could/should look into this as well. Since it's very important for our customers to have the query parameters for tracking instances.
In Gaia this was hacked in later as well, because we needed it.

We could create a default set of parameters to send through, or work with options in the url. Since the default Vue app wouldn't use those query parameters.

Discussion about the usage of constants in the store.

I think the current implementation of a store is over complicated and inconsistent. Specially the way we use the index.js file with the constants.

Or we should go all the way with constants and use them everywhere. Or we are not using them at all.

If we go all the way, then we should use constants not only for mutations (btw I think we should name them "{{name_pc}}Mutations" instead of "{{name_pc}}MutationTypes", they are not "type" of mutations, they are all normal mutations) but for everything. So also for the values, the getters and so on. But this will lead to very unclear code. Even within a simple example:

export const Values = {
  FIRST_NAME: 'firstName',
  LAST_NAME: 'lastName',
};

export const Getters = {
  FULL_NAME: 'fullName',
};

export default {
  namespaced: true,
  state: {
    [Values.FIRST_NAME]: 'John',
    [Values.LAST_NAME]: 'Do',
  },
  getters: {
    [Getters.FULL_NAME]: ({ [Values.FIRST_NAME]: firstName, [Values.LAST_NAME]: lastName }) =>
      `${firstName} ${lastName}`,
  },
};

Compared that to:

export default {
  namespaced: true,
  state: {
    firstName: 'John',
    lastName: 'Do',
  },
  getters: {
    fullName: ({ firstName, lastName }) => `${firstName} ${lastName}`,
  },
};

Although I am normally a huge fan of using constants, I think for this case it will only add unnecessary clutters and complexity. And this is not (In my opinion) what Vue is designed for. So I would suggest to remove all the constants in the store.

Remove optimized SVGs

Currently both original and optimized SVGs are part of the files being committed. Can't the optimized SVGs be ignored? This way the repo of your project stays clean from rendered/compiled files.

Override of publicPath is not working

as /config/index.js example tried with:

"dev": "cross-env NODE_ENV=development node build/dev-server.js -- --publicPath=/v/vue-skeleton/

and

"dev": "cross-env NODE_ENV=development node build/dev-server.js --publicPath=/v/vue-skeleton/

but configManager.getVariable(VariableNames.PUBLIC_PATH) was always /

Improve constants in namespaced store modules

If I understand correctly, we want our namespaced store modules to provide the following:

  • A const for the namespace
  • A const for the name of each mutation, action and getter
  • An easy way to access the mutation, action, getter names prefixed with the namespace

I found the following structure to be useful to achieve this:

// the namespace itself
export const EntitiesNamespace = 'entities';

// action names
export const GET_COLLECTION = 'getCollection';
export const AUTOFETCH_COLLECTION_REFS = 'autoFetchCollectionRefs';
export const GET_ENTITY = 'getEntity';
// each action name prefixed with the namespace
export const EntitiesActions = { GET_COLLECTION, GET_ENTITY, AUTOFETCH_COLLECTION_REFS };

// mutation names
export const SET_COLLECTION_DATA = 'setCollectionData';
export const SET_ENTITY = 'setEntity';
// each mutation name prefixed with the namespace
export const EntitiesMutations = { SET_ENTITY, SET_COLLECTION_DATA };

// getter names
export const COLLECTION_ENTITIES = 'collectionEntities';
export const COLLECTION_FULL_ENTITIES = 'collectionFullEntities';
export const COLLECTION_TOTAL = 'collectionTotal';
// each getter name prefixed with the namespace
export const EntitiesGetters = {
  COLLECTION_ENTITIES,
  COLLECTION_TOTAL,
  COLLECTION_FULL_ENTITIES,
};

// this function will do the actual prefixing
prefixNamespace(EntitiesNamespace, EntitiesActions, EntitiesMutations, EntitiesGetters);

export default {
  namespaced: true,
  ...
};

It is technically possible to automatically build the objects for the prefixed constants based on the exports. The reason I create them statically first and then patch them afterwards with prefixNamespace is so our IDE can statically analyse the objects and understand the properties in them.

What do you think about this approach? Once I have some time, I can submit a PR for this. If someone else wants to pick this up, feel free.

Add/Use a Base SCSS structure

There are a couple of resets/base CSS functionality that I'm copying in each new project that I think should/could be easily included in the project.

I've create a branch "feature/base-scss" where I've added a simple reset (box-sizing, headings, paragraphs, lists).
Besides that I included folders for project specific "functions" and "mixins". Where we can place those that are specific for each project.

With this branch I'm just providing my opinion on how this could be. So please include you're suggestions.
The reason for this is that I think it would be good if there is a similar approach on base styling within each project.

The base can also include global copy styling. Which I think is really helpfull.

Upgrade TSLint

TSLint is updated and now has properly implemented the exclude functionality. We should update and enable linting again using the latest version.

Remove RoutePaths.js

In my opinion it is very confusing that we have the RouteNames.js and the RoutePaths.js. In practice I see a lot of developers using the RouteNames in one file and RoutePaths in an other, which leads to unclear code.

I think we should always use the route name for navigation and only the path for the declaration. Therefor there is no need to have a separate RoutePaths file. So the RoutePaths file should be removed.

Disable eslint on the dev server by default

We've implemented push pre-hooks that lints your files before pushing. It's kind of annoying when throwing errors when just fiddling with code. I think it feels a bit counterproductive. I'm suggesting to turn it off while runnning the dev server. And let the linting be done by the IDE.

BundleAnalyzerPlugin takes up a lot of resources on prod builds

We have the BundleAnalyzerPlugin enabled by default on prod builds. However, this may cause the build to consume a lot of memory or even crash (I just encountered this with a dev who was running Node v9). This is likely because it generates a stats file (generateStatsFile: true) which is a huge json file. This causes large memory consumption when node is trying to stringify the json.

What we can do is configure the stats file not to include irrelevant information. Some options (like source) make the stats object very big. However, I think it's worth considering removing the bundle anlyzer from the prod builds. Most of the time we run a build, we don't check the analyzer output. Instead, when running the yarn analyze command we execute a build just for that purpose. It will make the analyze command significantly slower, but I think we use it less often than we do production builds.

Imports are absolute should be relative.

All imports are written in a absolute way. Should be relative.

Why?

  • Conflict with node_modules
  • Not sure where file is located
  • Will have problems in the future.
  • Conflict with eslint

Example
src/config/localeConfig.js

import { PropertyNames, VariableNames } from 'data/enum/configNames';
import { getValue } from 'util/injector';
import { CONFIG_MANAGER } from 'data/Injectables';

const getLocaleConfig = () => {
  const configManager = getValue(CONFIG_MANAGER);

  const languages = configManager.getProperty(PropertyNames.AVAILABLE_LOCALES).map(locale => {
    if (typeof locale === 'string') {
      return {
        code: locale,
        urlPrefix: locale,
        translationKey: locale,
      };
    }
    return locale;
  });

  const config = {
    persistent: false,
    defaultCode: configManager.getProperty(PropertyNames.DEFAULT_LOCALE),
    languages,
  };

  return {
    localeEnabled: configManager.getVariable(VariableNames.LOCALE_ENABLED),
    localeRoutingEnabled: configManager.getVariable(VariableNames.LOCALE_ROUTING_ENABLED),
    config,
  };
};

export default getLocaleConfig;

Use url-loader instead of svg-inline-loader

The default loader for .svg is an svg-inline-loader. What is the reasoning behind this? This will inline the svg as an svg tag (so <svg .... </svg>)

The result of this is when you use an svg in your styling:

background-image: url('some-svg.svg');

The result will be an svg tag inside your css:

background-image: url('<svg .... </svg>');

Which is not valid syntax. If you do want to use the inline loader, I think it's a better to explicitly opt-in to it in your import:

import svgTag from '!!svg-inline-loader!./some-svg.svg';

$store.getters.translation undefined error

Hi DJ HJ! 🎵

Your starter is amazing, but I had some issues.

When using the multi-language site and want to access the Vuex of the translations, for example, this.$store.getters.translation.home.title, Vue does not yet recognize any translation property and throw undefined error. This happens only if we load the site for the first time on the page that requires that store. The weird is that if I enter the site with the second language it works correctly.

Config file

src/config/config.js

variables: {
 [VariableNames.LOCALE_ENABLED]: true,
 [VariableNames.LOCALE_ROUTING_ENABLED]: true,
}

properties: {
 [PropertyNames.DEFAULT_LOCALE]: 'en-gb',
 [PropertyNames.AVAILABLE_LOCALES]: ['en-gb','es-es'],
}

Locale files

static/locale/en-gb.json

{ "home":{ "title":"page home" } }

static/locale/es-es.json

{ "home":{ "title":"página home" } }

Home page

src/page/HomePage/HomePage.js

export default {
 name: 'HomePage',
 mounted(){
  console.log(this.$store.getters.translation.home.title);
 }
};

If the error is mine do not hesitate to tell me. And thanks for sharing this starter. 💋 💋

.eslintignore - src/vendor/**/*js not working

When i run the code yarn prettify, Eslint is not ignoring the vendor folder completely. I do not know if the problem is because I add one more folder.
src / vendor / gsap / ...

.eslintignore

build/*.js bin/*.js config/*.js src/vendor/**/*.js

screen shot 2017-10-04 at 2 04 17 am

Load "business" GSAP Plugins

With the GSAP library installed from NPM, we don't get the extra Business plugins.
By default it's not possible to load them, because they all require 'TweenLite' from the folder where you put it.

For a current project I'm putting the extra plugins in the vendor/gsap folder. And adding a resolve alias for Webpack. This makes it possible to load the external plugins.

I suggest we can always add this in the skeleton, since it shouldn't break anything anyway.

In the webpack.base I've added this to the resolve alias object:
'TweenLite': path.resolve(projectRoot, 'node_modules/gsap/src/uncompressed/TweenLite'),

Suggestion: use TypeScript where possible

The skeleton currently has typescript support, but all of the modules are plain JS by default. Some modules might be impractical to write in TS (like the components), but is there any reason not to do easy ones in TS? For example, the utils. Even if your project does not use typescript, you still get the benefit from IDEs like Webstorm better understanding the typings of the skeleton code.

Possibility to add Favicon webpack generator

Can the favicon generator be added?

I added it manually and it worked fine.

Add static/image/favicon.png

package.json

"favicons-webpack-plugin": "^0.0.7"

build/webpack.prod.conf.js

const FaviconsWebpackPlugin = require('favicons-webpack-plugin')

new FaviconsWebpackPlugin({
  logo:path.resolve(__dirname, '../static/image/favicon.png'),
  prefixconfig.build.versionPath + "static/favicons/icon-[hash]",
  emitStatsfalse,
  statsFilename'iconstats-[hash].json',
  persistentCachefalse,
  injecttrue,
  background'#fff',
  title: '',
  icons{
    androidtrue,
    appleIcontrue,
    appleStartupfalse,
    coastfalse,
    faviconstrue,
    firefoxtrue,
    opengraphtrue,
    twittertrue,
    yandextrue,
    windowstrue
   }
})

😘 😘 😘 😘 😘

Remove global component registration

Currently we have a component/index.js module where you can globally register components. Even though this provide somewhat of a convenience, I think it's better to explicitly import components when we want to use them. This makes it clearer where the components come from.

Furthermore, this construction has caused circular dependency problems for me. When a component is imported this way and uses some constants from a vuex store module, these exports may be undefined at the moment the component module is parsed.

Add option to render server side (SSR)

I really like this scaffolding solution that you are building here. Seems quite well thought and build for big applications.
Would be very useful to have the option to do SSR first.
Is this something in your roadmap?

Thank you

Enable strict compiler options by default in TypeScript

When using vue-skeleton, everyone has the freedom to change the tsconfig.json compiler options to best serve their project. However, I think it would be good to have a more strict set of options by default. This will improve stability of our code. My suggestion is to add strict: true. This will set all of the following to true:

  • noImplicitAny
  • noImplicitThis
  • alwaysStrict
  • strictNullChecks
  • strictFunctionTypes
  • strictPropertyInitialization

In my experience, I think noImplicitAny and strictNullChecks have the largest advantage in terms of preventing errors at runtime. You can read an explanation here and here

Should we add a "Scoped Hover" mixin as a default

In "seng-scss" we have a "hover" mixin. But unfortunately this isn't working the way it's supposed to work from within the node-module.
The idea is to use a global class (most of the time a touch check from modernizr) as a prefix to the element. And then add :hover to the rule before displaying all content.
I think this is a nice solution to easily maintain hover states for supported devices only.

The problem with this is that we're working with CSS modules, where the local classes will interfere with the global classes. And also, by default, the modernizr isn't set-up to add the notouch class.

For the last couple of projects @larsvanbraam and myself used an adaptation from the hover mixin within our projects where we put the mixin in the global scope, and add the local selector to the mixin.
We've put this in asset/style/util/mixin/ and I think this would be a good idea to keep it by default there.
This will make sure the target is targeted correctly and we are easily able to update the check for when you want to support this custom hover functionality.

The mixin is as following:

@mixin scoped-hover($selector: null, $extraSelector: null) {
	// Add the no-touchevents to the global scope and locally use the provided selector
	:global .no-touchevents {
		:local {
			#{$selector}:hover {
				@content;
			}
		}
	}
	// When we have an extra selector like 'is-hover' we want to use that in the global selector
	@if $extraSelector {
		:global .no-touchevents #{$extraSelector} {
			:local {
				#{$selector} {
					@content;
				}
			}
		}
	}
}

Usage of this would be to put outside of the :local scope the following code:

@include scoped-hover('.link') {
	color: red;
}

We could remove the .no-touchevent, because the Modernizr set-up is empty by default. Or keep it as an option somehow.

Very curious on more ideas about this, and what you think.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.