
(И не стесняйтесь писать любые комментарии в @iamakulov)
Size: a a a
crossenv
, babelcli
, d3.js
и т.п.).crossenv
, babelcli
, d3.js
и т.п.).npm ls | grep -E "babelcli|crossenv|cross-env.js|d3.js|fabric-js|ffmepg|gruntcli|http-proxy.js|jquery.js|mariadb|mongose|mssql.js|mssql-node|mysqljs|nodecaffe|nodefabric|node-fabric|nodeffmpeg|nodemailer-js|nodemailer.js|nodemssql|node-opencv|node-opensl|node-openssl|noderequest|nodesass|nodesqlite|node-sqlite|node-tkinter|opencv.js|openssl.js|proxy.js|shadowsock|smb|sqlite.js|sqliter|sqlserver|tkinter"
wheel
вместо депрекейтнутого mousewheel
. Добавились данные для Firefox: https://gist.github.com/iamakulov/45803e89db2eb44a7a6be33a80ffcab7key={some unique ID}
. Этот атрибут помогает Реакту реиспользовать DOM-узлы, если вы переставляете элементы массива местами. Выглядит он так:<div>
{articles.map(article =>
<ArticlePreview key={article.id} article={article} />
)}
</div>
key
— это помочь Реакту избежать удаления и пересоздания элементов. Оказывается, его можно использовать с прямо противоположной целью — заставить Реакт лишний раз перемонтировать один и тот же элемент. Чтобы сделать это, нужно задать элементу одно значение key:<Image key="image-foo" />
<Image key="image-bar" />
key
, Реакт считает, что изменяется сам компонент. Поэтому вместо просто передачи пропов в уже существующий компонент он отмонтирует старый экземпляр, а затем примонтирует новый. У старого экземпляра при этом вызовутся колбеки componentWillUnmout()
, а у нового — конструктор и componentWillMount()
.react-table
). Подход с key
немного удобнее, чем с заменой компонента на null
и обратно — для него нужен только один вызов render
, а не два.import
и export
:// index.js
require("@std/esm")
module.exports = require("./main.mjs").default
// main.mjs
export default function() {
// ...
}
require.extensions
. Чтобы добавить новый обработчик, нужно добавить в этот объект новое функцию с полем, соответствующим расширению:require.extensions['.es'] = function (module, filename) {
// ...
}
require.extensions
, будет вызываться каждый раз, когда вы зареквайрите новый файл с соответствующим расширением. Что делать дальше, зависит от того, как вы хотите обработать файл.@std/esm
. Это делается вот так:require.extensions['.mjs'] = function (module, filename) {
var content = fs.readFileSync(filename, 'utf8');
var transpiledContent = transpileImportsExports(content);
module._compile(transpiledContent, filename);
}
module._compile
— это метод, который интерпретирует JS-код стандартным образом — парсит его, сохраняет экспорты и передаёт экспорты наружу. Сама Node.js использует его же для загрузки обычных .js-файлов.)module.exports
. Вот так, например, можно импортировать текстовый файл как строку:require.extensions['.txt'] = function (module, filename) {
const text = fs.readFileSync(filename, 'utf8');
module.exports = text;
}
require.extensions
module.exports
require.extensions
в реальных проектах лучше не использовать, потому что это замедляет загрузку файлов — и тех, которые вы конвертируете на лету, и остальных. Это подходит только для определённых библиотек — вроде этого @std/esm
или babel-register
. Если вам нужно компилировать код в обычном проекте, воспользуйтесь сборщиками кода вроде babel или webpack.import
и export
:// index.js
require("@std/esm")
module.exports = require("./main.mjs").default
// main.mjs
export default function() {
// ...
}
require.extensions
. Чтобы добавить новый обработчик, нужно добавить в этот объект новое функцию с полем, соответствующим расширению:require.extensions['.es'] = function (module, filename) {
// ...
}
require.extensions
, будет вызываться каждый раз, когда вы зареквайрите новый файл с соответствующим расширением. Что делать дальше, зависит от того, как вы хотите обработать файл.@std/esm
. Это делается вот так:require.extensions['.mjs'] = function (module, filename) {
var content = fs.readFileSync(filename, 'utf8');
var transpiledContent = transpileImportsExports(content);
module._compile(transpiledContent, filename);
}
module._compile
— это метод, который интерпретирует JS-код стандартным образом — парсит его, сохраняет экспорты и передаёт экспорты наружу. Сама Node.js использует его же для загрузки обычных .js-файлов.)module.exports
. Вот так, например, можно импортировать текстовый файл как строку:require.extensions['.txt'] = function (module, filename) {
const text = fs.readFileSync(filename, 'utf8');
module.exports = text;
}
require.extensions
module.exports
require.extensions
в реальных проектах лучше не использовать, потому что это замедляет загрузку файлов — и тех, которые вы конвертируете на лету, и остальных. Это подходит только для определённых библиотек — вроде этого @std/esm
или babel-register
. Если вам нужно компилировать код в обычном проекте, воспользуйтесь сборщиками кода вроде babel или webpack.@std/esm
использует более сложный подход. Этот пакет не просто добавляет обработчики для новых типов файлов, но и оборачивает их в свои функции (и обработчики для старых типов файлов тоже). Насколько я понимаю, это используется для большей гибкости: https://web.facebook.com/notes/ivan-akulov-about-frontend/how-to-compile-require-in-nodejs-on-the-fly/845823175583544/?comment_id=845865748912620element.getBoundingClientRect()
— медленный вызов. Не используйте его в часто вызываемых функциях — откладывайте его вызовы с помощью _.debounce или избавьтесь от него совсем.element.getBoundingClientRect()
медленный, потому что при каждом вызове он заставляет браузер пересчитывать лэйаут страницы. Вот другие браузерные АПИ, которые тоже вызывают такой эффект: https://gist.github.com/paulirish/5d52fb081b3570c81e3agetBoundingClientRect()
на самом деле перевычисляет лэйаут не прямо при каждом вызове, а только если он изменился.