npm i
это короткий вариант npm install
npm i name
установит пакет name версии отмеченной тегом latest (тэг по умолчанию)npm i name@tag
установит пакет name версии отмеченной тегом tagnpm i name@5
установит пакет name версии 5.x.x где x.x - последний из 5npm i name@5.3
установит пакет name версии 5.3.x где x - последний из 5.3npm i name@5.3.1
установит пакет name версии 5.3.1--save
или его короткий вариант -S
сохранит зависимость в package.json в секции dependencies, с некоторых пор это поведение по умолчанию при наличии package.json--save-dev
или его короткий вариант -D
сохранит зависимость в package.json в секции devDependenciesМожно ли обойтись обычным js?Можно. TypeScript лишь добавляет к JavaScript статическую типизацию в компайл-тайм. После компиляции будет все тот же JS.
Какие будут плюсы?Главный плюс, ИМХО, - скорость разработки за счет подсказок IDE и автодополнения, больше авторефакторингов. Ну и возможность ограничить использование функций/методов от нежелательного использования тоже плюс. А если еще и проектировать доменную модель на типах, то можно сразу видеть, если что-то не сходится, еще до написания логики.
Не будет ли много лишней писанины по сравнению с чистым js?Большинство типов TypeScript способен вывести. Далеко не Хиндли-Милнер конечно, но тоже хорошо. Я пишу больше в ФП стиле, с редкой примесью структурно-процедурного при описании эффектов, так у меня явные указания типов присутствуют только в сигнатурах функций. В самой логике код неотличим от обычного JS, но с хорошей проверкой типов.
Будет ли сложно хранить скомпилированный js?Как и любые другие артефакты сборки, скомпилированный JS хранить не нужно. Компилируйте непосредственно перед выкладыванием на продакшен, а в git храните лишь TS код + настройки компилятора. А в dev среде вообще можно запускаться через модуль ts-node.
const setup = {port:8000}
const express = require ('express');
const puppeteer = require('puppeteer');
const app = express ();
app.get('/', (req, res) => {
const url = req.query.url;
// вот тут Вы на каждый запрос создаете весьма тяжелую функцию
// в ней 203 AST ноды
// и она жрет в среднем 220КБ оперативы
// (node: 14.4.0; v8: 8.1.307.31-node.33, мерил через process.memoryUsage().heapUsed)
let scrape = async () => {
// а еще на каждый запрос запускам новый браузер
// у ноды это особо памяти не отнимет, а вот у системы - прилично
const browser = await puppeteer.launch({args: ['--no-sandbox']});
const page = await browser.newPage();
// еще и разрешаем запросу из браузера жить вечно
// если конечно сервак не оборвет коннект
await page.setDefaultNavigationTimeout(0);
await page.setUserAgent('Mozilla/5.0 (Linux; Android 7.0; NEM-L51) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.81 Mobile Safari/537.36');
await page.setViewport({width: 375, height: 812});
// куда мы отправляем браузер?
// переменная url у нас из req.query.url - а следовательно начинается с /
// то есть без хоста и протокола...
await page.goto(url);
// что-то мне подсказывает, что это работает не совсем так
// как Вы ожидаете
// https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pageevaluatepagefunction-args
// читаем: If the function passed to the page.evaluate returns a non-Serializable value, then page.evaluate resolves to undefined
const bottomSheet = await page.evaluate(() => {
return document.querySelector('div[data-marker="bottom-sheet"]');
});
// так как undefined !== null данное условие всегда истинно
if (bottomSheet !== null) {
// здесь по идее придет Promise.reject который мы не ловим (об этом ниже)
await page.click('div[data-marker="bottom-sheet"] button');
}
// и еще раз... ловите доку на нужный метод:
// https://github.com/puppeteer/puppeteer/blob/main/docs/api.md#pageselector
const phoneButton = await page.evaluate(() => {
return document.querySelector('a[data-marker="item-contact-bar/call"]');
});
// всегда ложное условие...
if (phoneButton === null) {
await browser.close();
return false; // ...с return внутри...
}
// еще 1 способ зависнуть (дефолтный таймаут 30 сек)
await page.waitForSelector('a[data-marker="item-contact-bar/call"]');
await page.click('a[data-marker="item-contact-bar/call"]');
try {
await page.waitForSelector('span[data-marker="phone-popup/phone-number"]');
} catch (e) {
await browser.close();
return false;
}
const result = await page.evaluate(() => {
console.log('phone', document.querySelector('span[data-marker="phone-popup/phone-number"]'));
return document.querySelector('span[data-marker="phone-popup/phone-number"]').innerHTML;
});
await browser.close();
return result;
};
// не ловим reject промиса
// и в случае reject не завершаем запрос
// и он тоже висит в памяти
scrape().then((value) => {
console.log(value);
if (value === false)
res.send(500);
// при value === false будет запись в закрытый поток... (или у express есть защита от дурака?)
res.send(value);
// абсолютно бесполезное действие...
scrape = null;
});
});
app.get('/test', (req, res) => {
res.send('Тест');
});
app.listen(setup.port, () => {
console.log('Сервер: порт %s - старт!', setup.port);
});
export default function({ types: t }) {
return {
visitor: {
Identifier(path) {
if(path.isIdentifier({ name: 'test' })) {
path.parentPath.get('init').node.value = 777
}
}
}
};
};
// Для класса ClassName
console.dir(ClassName.prototype, {showHidden: true});
// Для любого объекта или инстанса класса obj
console.dir(Object.getPrototypeOf(obj), {showHidden: true});
class SomeClass extends Array {}
function collectPrototypesChain(obj) {
const proto = Object.getPrototypeOf(obj);
if(!proto) { return null; }
const {name} = proto.constructor;
return {name, proto, next: collectPrototypesChain(proto)};
}
console.dir(collectPrototypesChain(new SomeClass()), {showHidden: true, depth: 4});
var app = require('express')();
var http = require('http');
var server1 = http.createServer(app);
var server2 = http.createServer(app);
server1.listen(PORT1, ADDRESS1);
server2.listen(PORT2, ADDRESS2);
что-то мне кажется что надо слеши экранировать пробовал так /\ ничего не выходитДа, обратный слэш нужно экранировать, так как он сам является экранирующим символом, прямой же слэш не экранирует, поэтому ничего не выходит
path.normalize( '//192.168.1.5/C$/data/data.json' )
.then(lefts => {
return Promise.all(
lefts.map(left => models.db.l_d.findOne({where: {id: left.l_d.id}})
.then(ld => ld.getMains())
)
).then(mains => mains.flatMap((main, i) => main.map(m => ({
data: data.name,
dataId: data.Id,
left: lefts[i].name,
leftId: lefts[i].id,
main: m.name,
mainId: m.id,
linkId: m.ld_m.id
}))));
}).then(
result => console.log(result),
err => console.log(err)
)
Советую получше изучить промисы// A.js
class A {
constructor(some_var) {
this.some_var = some_var;
}
do() {
console.log(this.some_var);
}
}
module.exports = A;
// index.js
const A = require('./A');
function print_it(param) {
const a = new A(param);
a.do();
}
print_it('wow'); // В консоли должно вывестись: wow
print_it('123'); // В консоли должно вывестись: 123
location /ws {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
Как запустить процесс сервера и сделать так, что бы можно было закрыть консоль и он автоматически перезапускался при падении и запускался при перезагрузке VDSpm2