Merge branch 'webpack-4-dart-sass' into shigusegubu

* webpack-4-dart-sass:
  fix prod build
  Fix small mistake in Polish translation
  fixed build speed
  fix tests
  attempt 2
  firefox
  attempt at making it work
  karma stuff, still broken tho
  more rules
  all the failing rules
  revert unnecessary changes
  update node
  fix obvious bug
  Webpack 4, ESLint with Vue, Node-sass, updated dependencies overall. New linting.
This commit is contained in:
Henry Jameson 2019-05-13 22:00:21 +03:00
commit fe222c9c03
17 changed files with 3285 additions and 1536 deletions

View file

@ -1,14 +1,17 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
extends: 'standard',
extends: [
'standard',
'plugin:vue/recommended'
],
// required to lint *.vue files
plugins: [
'html'
'vue'
],
// add your custom rules here
rules: {
@ -17,6 +20,28 @@ module.exports = {
// allow async-await
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
// Webpack 4 update commit, most of these probably should be fixed and removed in a separate MR
// A lot of errors come from .vue files that are now properly linted
'vue/valid-v-if': 1,
'vue/use-v-on-exact': 1,
'vue/no-parsing-error': 1,
'vue/require-v-for-key': 1,
'vue/valid-v-for': 1,
'vue/require-prop-types': 1,
'vue/no-use-v-if-with-v-for': 1,
'indent': 1,
'import/first': 1, // ????
'import-first': 1,
'object-curly-spacing': 1,
'prefer-promise-reject-errors': 1,
'eol-last': 1,
'no-return-await': 1,
'no-multi-spaces': 1,
'no-trailing-spaces': 1,
'no-unused-expressions': 1,
'no-mixed-operators': 1,
'camelcase': 1,
'no-multiple-empty-lines': 1
}
}

View file

@ -1,7 +1,7 @@
# This file is a template, and might need editing before it works on your project.
# Official framework image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/node/tags/
image: node:7
image: node:8
stages:
- lint
@ -16,7 +16,12 @@ lint:
test:
stage: test
variables:
APT_CACHE_DIR: apt-cache
script:
- mkdir -pv $APT_CACHE_DIR && apt-get -qq update
- apt install firefox-esr -y --no-install-recommends
- firefox --version
- yarn
- npm run unit

View file

@ -1,61 +1,64 @@
var path = require('path')
var config = require('../config')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var sass = require('sass')
var MiniCssExtractPlugin = require('mini-css-extract-plugin')
exports.assetsPath = function (_path) {
var assetsSubDirectory = process.env.NODE_ENV === 'production'
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
? config.build.assetsSubDirectory
: config.dev.assetsSubDirectory
return path.posix.join(assetsSubDirectory, _path)
}
exports.cssLoaders = function (options) {
options = options || {}
// generate loader string to be used with extract text plugin
function generateLoaders (loaders) {
var sourceLoader = loaders.map(function (loader) {
var extraParamChar
if (/\?/.test(loader)) {
loader = loader.replace(/\?/, '-loader?')
extraParamChar = '&'
} else {
loader = loader + '-loader'
extraParamChar = '?'
}
return loader + (options.sourceMap ? extraParamChar + 'sourceMap' : '')
}).join('!')
function generateLoaders (loaders) {
// Extract CSS when that option is specified
// (which is the case during production build)
if (options.extract) {
return ExtractTextPlugin.extract('vue-style-loader', sourceLoader)
return [MiniCssExtractPlugin.loader].concat(loaders)
} else {
return ['vue-style-loader', sourceLoader].join('!')
return ['vue-style-loader'].concat(loaders)
}
}
// http://vuejs.github.io/vue-loader/configurations/extract-css.html
return {
css: generateLoaders(['css']),
postcss: generateLoaders(['css']),
less: generateLoaders(['css', 'less']),
sass: generateLoaders(['css', 'sass?indentedSyntax']),
scss: generateLoaders(['css', 'sass']),
stylus: generateLoaders(['css', 'stylus']),
styl: generateLoaders(['css', 'stylus'])
}
return [
{
test: /\.(post)?css$/,
use: generateLoaders(['css-loader']),
},
{
test: /\.less$/,
use: generateLoaders(['css-loader', 'less-loader']),
},
{
test: /\.sass$/,
use: generateLoaders([
'css-loader',
{
loader: 'sass-loader',
options: {
indentedSyntax: true
}
}
])
},
{
test: /\.scss$/,
use: generateLoaders(['css-loader', 'sass-loader'])
},
{
test: /\.styl(us)?$/,
use: generateLoaders(['css-loader', 'stylus-loader']),
},
]
}
// Generate loaders for standalone style files (outside of .vue)
exports.styleLoaders = function (options) {
var output = []
var loaders = exports.cssLoaders(options)
for (var extension in loaders) {
var loader = loaders[extension]
output.push({
test: new RegExp('\\.' + extension + '$'),
loader: loader
})
}
var output = exports.cssLoaders(options)
console.log(output)
return output
}

View file

@ -20,9 +20,16 @@ module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
filename: '[name].js'
},
optimization: {
splitChunks: {
chunks: 'all'
}
},
resolve: {
extensions: ['', '.js', '.vue'],
fallback: [path.join(__dirname, '../node_modules')],
extensions: ['.js', '.vue'],
modules: [
path.join(__dirname, '../node_modules')
],
alias: {
'vue$': 'vue/dist/vue.runtime.common',
'src': path.resolve(__dirname, '../src'),
@ -30,67 +37,53 @@ module.exports = {
'components': path.resolve(__dirname, '../src/components')
}
},
resolveLoader: {
fallback: [path.join(__dirname, '../node_modules')]
},
module: {
noParse: /node_modules\/localforage\/dist\/localforage.js/,
preLoaders: [
rules: [
{
test: /\.vue$/,
loader: 'eslint',
enforce: 'pre',
test: /\.(js|vue)$/,
include: projectRoot,
exclude: /node_modules/
exclude: /node_modules/,
use: {
loader: 'eslint-loader',
options: {
formatter: require('eslint-friendly-formatter'),
sourceMap: config.build.productionSourceMap,
extract: true
}
}
},
{
test: /\.js$/,
loader: 'eslint',
include: projectRoot,
exclude: /node_modules/
}
],
loaders: [
{
test: /\.vue$/,
loader: 'vue'
use: 'vue-loader'
},
{
test: /\.jsx?$/,
loader: 'babel',
include: projectRoot,
exclude: /node_modules\/(?!tributejs)/
},
{
test: /\.json$/,
loader: 'json'
exclude: /node_modules\/(?!tributejs)/,
use: 'babel-loader'
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
use: {
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
use: {
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
}
]
},
eslint: {
formatter: require('eslint-friendly-formatter')
},
vue: {
loaders: utils.cssLoaders({ sourceMap: useCssSourceMap }),
postcss: [
require('autoprefixer')({
browsers: ['last 2 versions']
})
},
]
},
plugins: [

View file

@ -12,8 +12,9 @@ Object.keys(baseWebpackConfig.entry).forEach(function (name) {
module.exports = merge(baseWebpackConfig, {
module: {
loaders: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap })
},
mode: 'development',
// eval-source-map is faster for development
devtool: '#eval-source-map',
plugins: [
@ -23,9 +24,7 @@ module.exports = merge(baseWebpackConfig, {
'DEV_OVERRIDES': JSON.stringify(config.dev.settings)
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',

View file

@ -4,7 +4,7 @@ var utils = require('./utils')
var webpack = require('webpack')
var merge = require('webpack-merge')
var baseWebpackConfig = require('./webpack.base.conf')
var ExtractTextPlugin = require('extract-text-webpack-plugin')
var MiniCssExtractPlugin = require('mini-css-extract-plugin')
var HtmlWebpackPlugin = require('html-webpack-plugin')
var env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
@ -13,23 +13,25 @@ var env = process.env.NODE_ENV === 'testing'
let commitHash = require('child_process')
.execSync('git rev-parse --short HEAD')
.toString();
console.log(commitHash)
var webpackConfig = merge(baseWebpackConfig, {
mode: 'production',
module: {
loaders: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true })
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, extract: true })
},
devtool: config.build.productionSourceMap ? '#source-map' : false,
optimization: {
minimize: true,
splitChunks: {
chunks: 'all'
}
},
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
vue: {
loaders: utils.cssLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
chunkFilename: utils.assetsPath('js/[name].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/workflow/production.html
@ -38,14 +40,10 @@ var webpackConfig = merge(baseWebpackConfig, {
'COMMIT_HASH': JSON.stringify(commitHash),
'DEV_OVERRIDES': JSON.stringify(undefined)
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
}),
new webpack.optimize.OccurenceOrderPlugin(),
// extract css into its own file
new ExtractTextPlugin(utils.assetsPath('css/[name].[contenthash].css')),
new MiniCssExtractPlugin({
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
@ -67,25 +65,11 @@ var webpackConfig = merge(baseWebpackConfig, {
chunksSortMode: 'dependency'
}),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
})
// new webpack.optimize.SplitChunksPlugin({
// name: ['app', 'vendor']
// }),
]
})

View file

@ -11,7 +11,8 @@
"unit:watch": "karma start test/unit/karma.conf.js --single-run=false",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs",
"lint-fix": "eslint --fix --ext .js,.vue src test/unit/specs test/e2e/specs"
},
"dependencies": {
"babel-plugin-add-module-exports": "^0.2.1",
@ -21,12 +22,10 @@
"diff": "^3.0.1",
"karma-mocha-reporter": "^2.2.1",
"localforage": "^1.5.0",
"node-sass": "^3.10.1",
"object-path": "^0.11.3",
"phoenix": "^1.3.0",
"popper.js": "^1.14.7",
"sanitize-html": "^1.13.0",
"sass-loader": "^4.0.2",
"v-click-outside": "^2.1.1",
"vue": "^2.5.13",
"vue-chat-scroll": "^1.2.1",
@ -46,7 +45,7 @@
"babel-core": "^6.0.0",
"babel-eslint": "^7.0.0",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^6.0.0",
"babel-loader": "^7.0.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.0.0",
"babel-plugin-transform-vue-jsx": "3",
@ -59,52 +58,55 @@
"chromedriver": "^2.21.2",
"connect-history-api-fallback": "^1.1.0",
"cross-spawn": "^4.0.2",
"css-loader": "^0.25.0",
"eslint": "^3.7.1",
"eslint-config-standard": "^6.1.0",
"css-loader": "^0.28.0",
"eslint": "^5.16.0",
"eslint-config-standard": "^12.0.0",
"eslint-friendly-formatter": "^2.0.5",
"eslint-loader": "^1.5.0",
"eslint-plugin-html": "^1.5.5",
"eslint-plugin-promise": "^2.0.1",
"eslint-plugin-standard": "^2.0.1",
"eslint-loader": "^2.1.0",
"eslint-plugin-import": "^2.13.0",
"eslint-plugin-node": "^7.0.0",
"eslint-plugin-promise": "^4.0.0",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.2.2",
"eventsource-polyfill": "^0.9.6",
"express": "^4.13.3",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"file-loader": "^3.0.1",
"function-bind": "^1.0.2",
"html-webpack-plugin": "^2.8.1",
"html-webpack-plugin": "^3.0.0",
"http-proxy-middleware": "^0.17.2",
"inject-loader": "^2.0.1",
"iso-639-1": "^2.0.3",
"isparta-loader": "^2.0.0",
"json-loader": "^0.5.4",
"karma": "^1.3.0",
"karma": "^3.0.0",
"karma-coverage": "^1.1.1",
"karma-mocha": "^1.2.0",
"karma-phantomjs-launcher": "^1.0.0",
"karma-sinon-chai": "^1.2.0",
"karma-firefox-launcher": "^1.1.0",
"karma-sinon-chai": "^2.0.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "0.0.26",
"karma-webpack": "^1.7.0",
"karma-webpack": "^4.0.0-rc.3",
"lodash": "^4.16.4",
"lolex": "^1.4.0",
"mini-css-extract-plugin": "^0.5.0",
"mocha": "^3.1.0",
"nightwatch": "^0.9.8",
"opn": "^4.0.2",
"ora": "^0.3.0",
"phantomjs-prebuilt": "^2.1.3",
"raw-loader": "^0.5.1",
"sass": "^1.17.3",
"sass-loader": "git://github.com/webpack-contrib/sass-loader",
"selenium-server": "2.53.1",
"semver": "^5.3.0",
"serviceworker-webpack-plugin": "0.2.3",
"serviceworker-webpack-plugin": "^1.0.0",
"shelljs": "^0.7.4",
"sinon": "^1.17.3",
"sinon": "^2.1.0",
"sinon-chai": "^2.8.0",
"url-loader": "^0.5.7",
"vue-loader": "^11.1.0",
"vue-style-loader": "^2.0.0",
"webpack": "^1.13.2",
"webpack-dev-middleware": "^1.8.3",
"url-loader": "^1.1.2",
"vue-loader": "^14.0.0",
"vue-style-loader": "^4.0.0",
"webpack": "^4.0.0",
"webpack-dev-middleware": "^3.6.0",
"webpack-hot-middleware": "^2.12.2",
"webpack-merge": "^0.14.1"
},

View file

@ -50,6 +50,10 @@
@import '../../_variables.scss';
.login-form {
display: flex;
flex-direction: column;
padding: 0.6em;
.btn {
min-height: 28px;
width: 10em;
@ -66,9 +70,30 @@
align-items: center;
justify-content: space-between;
}
}
.login {
.form-group {
display: flex;
flex-direction: column;
padding: 0.3em 0.5em 0.6em;
line-height:24px;
}
.form-bottom {
display: flex;
padding: 0.5em;
height: 32px;
button {
width: 10em;
}
p {
margin: 0.35em;
padding: 0.35em;
display: flex;
}
}
.error {
text-align: center;

View file

@ -155,7 +155,7 @@
}
}
.post-status-form, .login {
.post-status-form {
.form-bottom {
display: flex;
padding: 0.5em;

View file

@ -627,7 +627,7 @@ a.unmute {
flex: 1;
}
.timeline > {
.timeline :not(.panel-disabled) > {
.status-el:last-child {
border-radius: 0 0 $fallback--panelRadius $fallback--panelRadius;
border-radius: 0 0 var(--panelRadius, $fallback--panelRadius) var(--panelRadius, $fallback--panelRadius);

View file

@ -19,7 +19,7 @@ if (typeof arg === 'undefined') {
console.log('')
console.log('There are no other arguments or options. Make an issue if you encounter a bug or want')
console.log('some feature to be implemented. Merge requests are welcome as well.')
return
process.exit()
}
const english = require('./en.json')

View file

@ -363,7 +363,7 @@
"error_fetching": "Błąd pobierania",
"load_older": "Załaduj starsze statusy",
"no_retweet_hint": "Wpis oznaczony jako tylko dla obserwujących lub bezpośredni nie może zostać powtórzony",
"repeated": "powtórzono",
"repeated": "powtórzył(-a)",
"show_new": "Pokaż nowe",
"up_to_date": "Na bieżąco",
"no_more_statuses": "Brak kolejnych statusów",

View file

@ -1,7 +1,3 @@
// Polyfill fn.bind() for PhantomJS
/* eslint-disable no-extend-native */
Function.prototype.bind = require('function-bind')
// require all test files (files that ends with .spec.js)
const testsContext = require.context('./specs', true, /\.spec$/)
testsContext.keys().forEach(testsContext)
@ -9,5 +5,5 @@ testsContext.keys().forEach(testsContext)
// require all src files except main.js for coverage.
// you can also change this to match only the subset of files that
// you want coverage for.
const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
srcContext.keys().forEach(srcContext)
// const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
// srcContext.keys().forEach(srcContext)

View file

@ -13,7 +13,7 @@ var projectRoot = path.resolve(__dirname, '../../')
var webpackConfig = merge(baseConfig, {
// use inline sourcemap for karma-sourcemap-loader
module: {
loaders: utils.styleLoaders()
rules: utils.styleLoaders()
},
devtool: '#inline-source-map',
// vue: {
@ -53,11 +53,18 @@ module.exports = function (config) {
// 1. install corresponding karma launcher
// http://karma-runner.github.io/0.13/config/browsers.html
// 2. add it to the `browsers` array below.
browsers: ['PhantomJS'],
browsers: ['FirefoxHeadless'],
frameworks: ['mocha', 'sinon-chai'],
reporters: ['mocha'],
customLaunchers: {
'FirefoxHeadless': {
base: 'Firefox',
flags: [
'-headless',
]
}
},
files: [
'../../node_modules/@babel/polyfill/dist/polyfill.js',
'./index.js'
],
preprocessors: {

View file

@ -39,6 +39,7 @@ const externalProfileStore = new Vuex.Store({
getters: testGetters,
state: {
api: {
fetchers: {},
backendInteractor: backendInteractorService('')
},
interface: {
@ -106,6 +107,7 @@ const localProfileStore = new Vuex.Store({
getters: testGetters,
state: {
api: {
fetchers: {},
backendInteractor: backendInteractorService('')
},
interface: {

View file

@ -9,7 +9,7 @@ const mockTouchEvent = (x, y) => ({
]
})
describe.only('GestureService', () => {
describe('GestureService', () => {
describe('swipeGesture', () => {
it('calls the callback on a successful swipe', () => {
let swiped = false

4454
yarn.lock

File diff suppressed because it is too large Load diff