Как запретить входящее подключение в брандмауэре linux

Допустим, кто-либо с IP-адрессом1 92.168.34.63 надоедает вам, чтобы избавится от его запросов к вашему компьютеру, запустите следующую команду:

iptables -A INPUT -s 192.168.34.63 -j DROP

Проверить все правила можно командой:

iptables -L

 

Пишем собственную библиотеку при помощи webpack и es6


Два месяца назад я опубликовал starter-pack для react на основе webpack. Сегодня я узнал, что мне нужно почти то же самое, но без recat. Это упрощает установку, но есть еще некоторые сложные детали. Итак, я сделал новый репозиторий webpack-library-starter и собрал все то, что необходимо для создания JavaScript библиотеки.

Прежде всего, что я имел в виду под словами “ библиотека”

Мое определение библиотеки в контексте JavaScript — это фрагмент кода, обеспечивающий определенную функциональность. Он делает одну вещь и делает это хорошо. В идеале она не должна зависеть от других библиотек или фреймворков. Хороший пример — библиотека jQuery. React и vue.js также можно считать библиотекой.

Библиотека должна:

  • Быть доступна для использования в браузере, через тег <script>
  • Быть доступна через npm
  • Быть совместимой с системой модулей ES6(ES2015), commonjs, AMD.

Структура директорий

Я собираюсь создать следующую структуру каталогов:

+-- lib
|   +-- library.js
|   +-- library.min.js
+-- src
|   +-- index.js
+-- test

Где в src лежат исходные файлы, а в lib скомпилированная версия библиотеки. Это означает то, что точкой входа библиотеки будет файл в lib, а не в src.

The starter

Мне очень нравится новая спецификация ES6. Плохо то, что вокруг нее есть какая-то дополнительная обвязка. Когда-нибудь мы, вероятно, напишем такой JavaScript без необходимости транспилировать, но сегодня это не так. Обычно нам нужна интеграция babel. Babel может конвертировать наши файлы из ES6 в ES5, но он не предназначен для создания пакетов. Другими словами, если у нас есть следующие файлы:

+-- lib
+-- src
    +-- index.js (es6)
    +-- helpers.js (es6)

То используя babel мы получим:

+-- lib
|   +-- index.js (es5)
|   +-- helpers.js (es5)
+-- src
    +-- index.js (es6)
    +-- helpers.js (es6)

К сожалению, babel не разрешает imports/requires. Так что нам нужен bundler и, как вы можете догадаться, мой выбор для этого — webpack. То, чего я хочу достичь в итоге:

+-- lib
|   +-- library.js (es5)
|   +-- library.min.js (es5)
+-- src
    +-- index.js (es6)
    +-- helpers.js (es6)

npm команды

npm предоставляет хороший механизм для выполнения команд  — scripts. Мы должны иметь как минимум три:

"scripts": {
  "build": "...",
  "dev": "...",
  "test": "..."
}
  • npm run build — эта должна делать финальную минифицированную версию нашей библиотеки
  • npm run dev — аналогично build но не делает минификцию и продолжает работать в режиме наблюдения
  • npm run test — запуск тестов

Версии для разработки

npm run dev должна запускать webpack и делать файл — lib/library.js. Мы начинаем с файла конфигурации webpack:

// webpack.config.js

var webpack = require('webpack');
var path = require('path');
var libraryName = 'library';
var outputFile = libraryName + '.js';

var config = {
  entry: __dirname + '/src/index.js',
  devtool: 'source-map',
  output: {
    path: __dirname + '/lib',
    filename: outputFile,
    library: libraryName,
    libraryTarget: 'umd',
    umdNamedDefine: true
  },
  module: {
    loaders: [
      {
        test: /(\.jsx|\.js)$/,
        loader: 'babel',
        exclude: /(node_modules|bower_components)/
      },
      {
        test: /(\.jsx|\.js)$/,
        loader: "eslint-loader",
        exclude: /node_modules/
      }
    ]
  },
  resolve: {
    root: path.resolve('./src'),
    extensions: ['', '.js']
  }
};

module.exports = config;

Даже если у вас нет опыта работы с webpack, вы сможете понять, что делает этот конфигурационный файл. Определяем вход (entery) и выход (output) компиляции. Поле module говорит, что нужно применять для каждого файла во время обработки. В нашем случае это babel и ESLint где ESLint используется для проверки синтаксиса и правильности кода.

Тут небольшая уловка — несколько свойств, которые я пропустил. Речь идет обlibrary, libraryTarget и umdNamedDefine. Сначала я попробовал без них и на выходе из библиотеки я получил что-то вроде этого:

(function(modules) {
  var installedModules = {};

  function __webpack_require__(moduleId) {
    if(installedModules[moduleId]) return installedModules[moduleId].exports;

    var module = installedModules[moduleId] = {
      exports: {},
      id: moduleId,
      loaded: false
    };
    modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
    module.loaded = true;
    return module.exports;
  }

  __webpack_require__.m = modules;
  __webpack_require__.c = installedModules;
  __webpack_require__.p = "";

  return __webpack_require__(0);
})([
  function(module, exports) {
    // ... my code here
  }

Так выглядит каждый скомпилированный webpack’ом пакет. Он использует подход аналогичный browserify. Есть self-invoking функция, которая получает все модули, используемые в нашем приложении. Каждый из них остается позади индекса массива modules. В приведенном выше коде у нас есть только один модуль и __webpack_require__(0) эффективно запускает код в нашем src/index.js файле.

Наличие такого пакета не соответствует всем требованиям, упомянутым в начале этой статьи, поскольку мы ничего не экспортируем. Код будет скрыт для веб-страницы. Тем не менее, добавление library, libraryTarget и umdNamedDefine делают так, что webpack добавляет в начале файла такой кусок кода:

(function webpackUniversalModuleDefinition(root, factory) {
  if(typeof exports === 'object' && typeof module === 'object')
    module.exports = factory();
  else if(typeof define === 'function' && define.amd)
    define("library", [], factory);
  else if(typeof exports === 'object')
    exports["library"] = factory();
  else
    root["library"] = factory();
})(this, function() {
return (function(modules) {
 ...
 ...

Установка libraryTarget в UMD означает что для конечного результата будет использоваться universal module definition. И действительно, этот фрагмент кода распознает среду и предоставляет надлежащий загрузочный механизм для нашей библиотеки.

Построение версии для разработки

Единственное различие между разработкой и production режимом для webpack — это минификация. Запуск npm run build должен собирать уменьшенную версию — library.min.js. webpack имеет хороший встроенный плагин для этого:

// webpack.config.js

...
var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
var env = process.env.WEBPACK_ENV;

var libraryName = 'library';
var plugins = [], outputFile;

if (env === 'build') {
  plugins.push(new UglifyJsPlugin({ minimize: true }));
  outputFile = libraryName + '.min.js';
} else {
  outputFile = libraryName + '.js';
}

var config = {
  entry: __dirname + '/src/index.js',
  devtool: 'source-map',
  output: { ... },
  module: { ... },
  resolve: { ... },
  plugins: plugins
};

module.exports = config;

UglifyJsPlugin сработает, если добавить его в массив плагинов. Тут еще кое что надо уточнить. Нам нужно условие, где мы даем указания webpack, какой пакет собирать (production или development). Одним из популярных подходов является определение переменной окружения и ее передача из командной строки. Например:

// package.json

"scripts": {
  "build": "WEBPACK_ENV=build webpack",
  "dev": "WEBPACK_ENV=dev webpack --progress --colors --watch"
}

(Обратите внимание на опцию --watch. Она заставляте webpack постоянно работать и наблюдать за изменениями)

Тестирование

Я обычно использую Mocha и Chai для тестирования, и это то, что я добавил в начале. Снова возникают сложности, Mocha не понимает ЕС6 файлы, но, к счастью babel решил эту проблему.

// package.json
"scripts": {
  ...
  "test": "mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js"
}

Важным элементом является опция --compilers. Она позволяет нам обрабатывать входящий файл перед его запуском.

Несколько других конфигурационных файлов

Babel получил некоторые серьезные изменения в новейшей версии 6. Теперь применяются preset для тех мест, для которых мы хотим получить преобразования. Один из самых простых способов — настроить это — .babelrc файл:

// .babelrc
{
  "presets": ["es2015"],
  "plugins": ["babel-plugin-add-module-exports"]
}

ESLint предоставляет то же самое, вот наш .eslintrc:

// .eslintrc
{
  "ecmaFeatures": {
    "globalReturn": true,
    "jsx": true,
    "modules": true
  },
  "env": {
    "browser": true,
    "es6": true,
    "node": true
  },
  "globals": {
    "document": false,
    "escape": false,
    "navigator": false,
    "unescape": false,
    "window": false,
    "describe": true,
    "before": true,
    "it": true,
    "expect": true,
    "sinon": true
  },
  "parser": "babel-eslint",
  "plugins": [],
  "rules": {
    // ... lots of lots of rules here
  }
}

Ссылки

Стартер доступен в GitHub здесь github.com/krasimir/webpack-library-starter.

Использованные инструменты:

  • webpack
  • Babel
  • ESLint
  • Mocha, Chai
  • UMD

Зависимости:

// package.json
"devDependencies": {
  "babel": "6.3.13",
  "babel-core": "6.1.18",
  "babel-eslint": "4.1.3",
  "babel-loader": "6.1.0",
  "babel-plugin-add-module-exports": "0.1.2",
  "babel-preset-es2015": "6.3.13",
  "chai": "3.4.1",
  "eslint": "1.7.2",
  "eslint-loader": "1.1.0",
  "mocha": "2.3.4",
  "webpack": "1.12.9"
}

typescript vs flow

За что я люблю typescript и не люблю flow.

По количеству фич Тайпскрипт и флоу практически одинаковы и на самом деле холивар тут разводить не стоит. Хотя отличия все же есть, например,
у тайпскипта есть дополнительные примитивы для классов реализующие полноценное ООП, числовые и строковые enum‘ы, а флоу умеет проходится по коду и предугадывать типы значений.

Первая вещь которая мне не нравится во флоу, то что он приучает писать невалидный код в .js файлах. Если однажды ваш коллега по отрасли вдруг захочет скопировать, например, ваш компонент в себе в проект не заглянув в исходный код, то у него ничего не получится, его сборщик сломается и ему придется задуматься о дополнительном слое сборки или даже о выносе кода в отдельный модуль, скорее всего, после того как он уже назвал примерные сроки, что может привести к проблемам с дедлайном. Так же джуниоры которые вместо ванильного js увидят вот это вот все с типами, могут сильно испугаться. В тайпскрипте, аналогично jsx и другим препроцессорам, файлы имеют явно расширения .ts или .tsx. Про поддержку в IDE я ничего говорить не стану, хотя интуиция подсказывает что тут проблемы тоже скорее всего всплывут.

PS: если мы используем flow comment types то все ок.

Второй минус flow в том, что он написан на мало известном для javascript сообщества языке — ocaml. Это замедлит его развитие, и если однажды фейсбук откажется от него, то умрет он в ту же секунду!

Напоследок наброшу субъективного:
Для flow мало тайпингов у внешних библиотек, большенство из них частичны.
По flow гораздо меньше обучающих материалов, в то время как по тайпскрипту даже есть курс на coursera.

У typescript почти в 2 раза больше звездочек на github, несмотря на то что оба проекта начались в 2014 году.

Сочетания клавиш windows 10

windows + l — сменить пользователя
ctrl + shft + esc — диспетчер задач
windows + e — новое окно проводника
windows + (s, q) — поиск
windows + D — свернуть/развернуть все окна
windows + Tab — показать все запущенные приложения
alt + пробел — открыть меню приложения (можно будет, например, свернуть или развернуть приложение без мышки)
alt + printScr — снимок текущего приложения
windows + e — открыть проводник

Как удалить все аудиозаписи в вк без vkopt

Как удалить все аудио-записи на странице, бесплатно, без регистрации и смс, без сторонних расширений.

Сделать это можно при помощи простого скрипта, выполняемого из консоли разработчика.


document.querySelectorAll('.audio_act._audio_act_delete').forEach(audioDeleteButton => audioDeleteButton.click())

Аналогично можно поступить и с видео-записями

document.querySelectorAll('#delete').forEach(videoDeleteButton => {videoDeleteButton.click()});

Отслеживание выполнения команд и системных вызовов

lsof — выводит все открытые файлы в системе.
strace — выводит все системные вызовы. Пример — strace echo ‘hello world’

Хоткеи для top:
M — обновить экран
T — сортировка по используемой рнзидентной памяти
P — использование цпу
u — отобразить процесс только для одного пользователя
f — выбрать другие параметры для отображения
? — статистика использования всех команд top

Как написать Virtual Dom

Есть 2 вещи, которые необходимо знать. Вам не нужно погружаться в исходный код React’а или других библиотек, они довольно большие и сложные, на самом деле Virtual DOM может быть написан в меньше чем 50 строк кода.

  1. Virtual DOM это аналог настоящего DOM
  2. Когда мы меняем что-то в дереве Virtual DOM , мы создаем новый Virtual DOM. Алгоритм сравнения двух деревьев вычисляет разницу и вносит только необходимые, минимальные правки в  настоящий DOM.

Читать далее Как написать Virtual Dom

html5 notification VS web push api

В чем разница между html5 notification и web push API?

html5 notification используется для отображения уведомлений с веб-страницы, в то время как Push API, используется для отправки уведомлений удаленно, даже если веб-страница неактивна.