Или как я улучшил бессерверный шаблон AWS NodeJS Typescript (aws-nodejs-typescript) с точки зрения как времени сборки, так и размера пакета, настроив настройку машинописного текста, webpack, serverless.yml и eslint.
Если ваш машинописный текст, eslint или webpack настраиваются медленно, вы можете воспользоваться приведенными ниже советами, чтобы оптимизировать их.
Оптимизация машинописного текста - tsconfig.json
- Включить только
**/*.ts
файлы и исключитьnode_modules
и каталоги сборки. - Удалите комментарии из пакета, установив
“removeComments”: true
вcompilerOptions
. - Включите инкрементные API-интерфейсы и API-интерфейсы для просмотра.
// tsconfig.json { "compilerOptions": { "lib": [ "es2017" ], "removeComments": true, "moduleResolution": "node", "resolveJsonModule": true, "noUnusedLocals": false, "noUnusedParameters": false, "sourceMap": true, "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "importHelpers": true, "incremental": true, "watch": true, "target": "es2017", "outDir": "lib" }, "include": [ "./**/*.ts" ], "exclude": [ "node_modules/**/*", ".serverless/**/*", ".webpack/**/*", "_warmup/**/*", ".vscode/**/*", "*.config.js", "**/*.js" ] }
Оптимизация eslint - .eslintrc.js
Теперь, когда tslint устарел, мы должны вместо него использовать eslint с typescript-eslint. Однако я не мог не заметить разницу в производительности после переключения, eslint был медленнее, чем tslint из коробки. Вот что вы можете сделать, чтобы извлечь из этого максимальную пользу:
- Настройте
.eslintignore
файл так, чтобы он игнорировалnode_modules
, а также файлы сборки и файлы без машинописного текста. - Используйте флаг
--cache
при запуске eslint, например:eslint --cache **/*.ts
. - Не расширяйте дорогостоящую
"plugin:@typescript-eslint/recommended-requiring-type-checking"
конфигурацию в конфигурации eslint. - Добавьте
.eslintignore
файл, чтобы игнорировать node_modules и каталоги сборки
//.eslintrc.js module.exports = { "extends": [ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "standard" ], "env": { "node": true }, "parser": "@typescript-eslint/parser", "plugins": [ "@typescript-eslint", ], "settings": { "import/parsers": { "@typescript-eslint/parser": [ ".ts", ".tsx" ] }, "import/resolver": { "typescript": {} } }, "parserOptions": { "project": "./tsconfig.json", "tsconfigRootDir": "./", "sourceType": "module", "ecmaVersion": 2018 }, "rules": { "@typescript-eslint/no-explicit-any": "off", } }
Добавьте .eslintignore
файл, чтобы игнорировать файлы, отличные от src, которые не нужно линтировать
//.eslintignore node_modules .serverless .vscode *.config.js .webpack _warmup **/*.js
Оптимизация webpack.config.js
- Установите webpack-node-externals, чтобы удалить неиспользуемые
node_modules
из сборки. - Установите
devtool
наcheap-module-eval-source-map
для разработки / локальных сборок. - Удалите ненужные расширения из свойства «разрешить».
- Исключите
node_modules
, а также каталоги build / non-src из правил загрузчика. - Оптимизируйте производительность сборки вашего веб-пакета с помощью этих советов.
- Отключите проверку типов в
ts-loader
и включите новый API часов. - Используйте fork-ts-webpack-checker-plugin для запуска проверки типов в отдельном процессе.
// webpack.config.js const path = require('path'); const slsw = require('serverless-webpack'); const nodeExternals = require('webpack-node-externals'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); module.exports = { context: __dirname, mode: slsw.lib.webpack.isLocal ? 'development' : 'production', entry: slsw.lib.entries, devtool: slsw.lib.webpack.isLocal ? 'cheap-module-eval-source-map' : 'source-map', resolve: { extensions: ['.mjs', '.json', '.ts'], symlinks: false, cacheWithContext: false, }, output: { libraryTarget: 'commonjs', path: path.join(__dirname, '.webpack'), filename: '[name].js', }, target: 'node', externals: [nodeExternals()], module: { rules: [ // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader` { test: /\.(tsx?)$/, loader: 'ts-loader', exclude: [ [ path.resolve(__dirname, 'node_modules'), path.resolve(__dirname, '.serverless'), path.resolve(__dirname, '.webpack'), ], ], options: { transpileOnly: true, experimentalWatchApi: true, }, }, ], }, plugins: [ // new ForkTsCheckerWebpackPlugin({ // eslint: true, // eslintOptions: { // cache: true // } // }) ], };
8. (Бонус) Обновление до webpack v5 https://webpack.js.org/migrate/5/
Оптимизация serverless.yml
- Для правильной настройки внешних узлов с помощью
serverless-webpack
plugin вам необходимо установить параметрcustom: webpack: includeModules
в файле serverless.yml, как указано здесь плагином serverless-webpack, чтобы правильно поддерживать плагин внешних компонентов узла webpack - Включите сжатие GZip, чтобы минимизировать размер возвращаемого ответа, установив
apiGateway:minimumCompressionSize: 1024
вserverless.yml
файле - Включите повторное использование соединений AWS, установив для
environment: AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
значение повторно использовать соединения HTTP
//serverless.yml service: name: aws-nodejs-typescript # app and org for use with dashboard.serverless.com #app: your-app-name #org: your-org-name custom: webpack: webpackConfig: ./webpack.config.js includeModules: true # Add the serverless-webpack plugin plugins: - serverless-webpack provider: name: aws runtime: nodejs10.x apiGateway: minimumCompressionSize: 1024 # Enable gzip compression for responses > 1 KB environment: AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1 functions: hello: handler: handler.hello events: - http: method: get path: hello
Полученные результаты:
Теперь давайте посмотрим на результаты после реализации вышеуказанных оптимизаций. Спасибо пользователю github sapher за его собственный отзыв о большом проекте после моего pull request. Это его результаты
До:
После:
Как видите, разница в размере файла 37 000% с 5,9 МБ до 13,8 КБ для первого файла, а 3410 % увеличение скорости сборки (с 45,5 секунды до 1,3 секунды!).
И это результаты в шаблоне проекта hello world без зависимостей.
Я сделал запрос на перенос здесь с этими изменениями в бессерверном репозитории, который уже был объединен в ноябре 2019 года.
Если ваш проект был создан ранее, вы можете обновить настройку вручную, посмотрев на изменения в запросе на вытягивание, на самом деле они очень небольшие, но, как вы можете видеть, весьма значительны.
Оптимизация общего размера пакета и скорости развертывания
Позже я смог сократить свои упакованные zip-файлы более чем наполовину и ускорить упаковку и развертывание за счет:
- Обновление до webpack v5
- используйте ускорение передачи s3 с помощью флага
aws-s3-accelerate
при запускеsls deploy
для более быстрой загрузки в s3 за дополнительную плату. - переключение с npm на yarn, чтобы использовать функцию autoclean, запустив
yarn autoclean — init
иyarn autoclean — force
, которые очищают мои node_modules и удаляют оттуда ненужные файлы благодаря этой проблеме github в serverless-webpack. - Настроить
serverless-webpack
плагин для использованияyarn autoclean
для включенногоnode_modules
и использовать мой настроенный.yarnclean
файл, добавив его в мой serverless.yml
//serverless.yml webpack: webpackConfig: ./webpack.config.js includeModules: true forceExclude: - aws-sdk packager: "yarn" packagerOptions: scripts: - yarn autoclean --init - rm .yarnclean && cat ../../.yarnclean >> .yarnclean && echo '\n*.ts' >> .yarnclean - rm -rf node_modules/aws-sdk - yarn autoclean --force
6. Настройка более продвинутого .yarnclean
файла, чем тот, который был создан с помощью yarn autoclean — init
, который также использует файлы, удаленные с помощью node-prune.
7. Принудительное удаление aws-sdk из моих пакетов с помощью packagerOptions.scripts
serverless-webpack Я заметил, что даже несмотря на то, что aws-sdk был заявлен как devDependency и исключался внешним pugin, он все еще добавлялся в мои пакеты через aws-xray-sdk-core
, в котором указано aws-sdk
в качестве зависимости вместо peerDependency, чтобы она все еще попала в мой пакет, для этого уже есть проблема с github в aws-xray-sdk.
Вышеупомянутые шаги помогли уменьшить размер пакета для одной из моих лямбда-выражений с 18 МБ до 7 МБ, а для других - с 11 МБ до 2,7 МБ.