Настройте проект JavaScript ES6, используя webpack, babel и eslint.

Оглавление —

Всякий раз, когда кто-то изучает новый язык программирования, с вероятностью 99% его первая программа будет Привет, мир программа. В этой пресловутой программе они должны печатать Hello World на своем экране/консоли. В зависимости от языка он может варьироваться от однострочной программы до многострочной только для печати этого Привет, мир.

В Javascript в старые времена (4-5 лет назад) можно было просто создать файл HTML с этим содержимым и открыть его в своих браузерах, чтобы увидеть Привет, мир печатаются в окнах их браузера (а также в консоли браузера).

<!DOCTYPE html>
<html> <head> <title>Hello World</title> </head> <body> <p>Hello World</p> <script> console.log('Hello World'); </script> </body>
</script>

Но по мере того, как экосистема JavaScript развивалась, этот процесс усложнялся (к лучшему). В этом уроке вы узнаете, как настроить этот тип проекта.

Предположения

  • Вы знаете Javascript (желательно немного es6).
  • У вас есть nodejs а также npm установлен в вашей системе (Руководство).

Полный код доступен на https://github.com/brijeshb42/hello-world-tutorial.

Часть 1

Откройте приложение терминала или командную строку и cd в каталог, где вы хотели бы создать этот проект. Предположим, что папка проекта называется hello-world в каком-то каталоге на вашем диске. Теперь введите эти команды —

  1. cd hello-world
  2. npm init --y

Это создаст package.json файл в hello-world каталог. package.json файл в вашем проекте, который используется nodejs а также npm чтобы отслеживать установленные пакеты и метаданные вашего проекта. Ваш package.json может выглядеть примерно так —

{ "name": "hello-world", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC"
}

Теперь добавьте веб-пакет и dev-сервер —

npm install webpack@3.11.1 webpack-dev-server --save-dev

на момент написания этой статьи установленная версия веб-пакета была 3.11.1.

Редактировать: версия была добавлена ​​позже в сообщении, потому что, так как этот учебник был опубликован, webpack была выпущена версия 4, которая имеет немного другую конфигурацию и может нарушить настройку этого руководства.

Создать src каталог внутри папки вашего проекта, а затем создайте index.js файл внутри него.

  1. mkdir src
  2. echo "console.log('Hello world');" > src/index.js

Это наша программа hello world, которая будет печатать Hello world в консоли браузера при запуске.

На этом этапе вы можете начать с написания файла конфигурации веб-пакета, чтобы связать ваши файлы для загрузки браузером.

Создать webpack.config.js файл в папке вашего проекта со следующим содержимым. Этот файл используется webpack для чтения вашей конфигурации и соответствующей сборки проекта.

const path = require('path'); module.exports = { entry: { bundle: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }
};

Теперь вы можете запустить эту команду для веб-пакета, чтобы загрузить файл записи и создать связанный файл js в dist каталог в корне каталога вашего проекта.

./node_modules/.bin/webpack

Это команда сборки, которая объединит все зависимости и создаст bundle.js файл, как указано в output вариант конфигурационного файла webpack. После выполнения этой команды вы увидите bundle.js файл в dist. Вы пока не можете загрузить этот js-файл, так как сначала вам нужен html-файл. Браузер загрузит этот файл, который, в свою очередь, загрузит файл js. Вы можете вручную создать index.html файл в dist с этим содержанием.

<script src="./bundle.js"></script>

Это минимальное количество html, необходимое для загрузки и запуска нашего связанного js. Теперь вы можете дважды щелкнуть этот html-файл, и он откроется в браузере. Вы можете открыть консоль браузера, используя CMD/CTRL + SHIFT + I чтобы увидеть результат. Давайте рассмотрим лучший способ, с помощью которого вам не нужно писать html-файл.

npm install html-webpack-plugin --save-dev

Это плагин веб-пакета, который автоматически генерирует index.html файл в dist с правильными ссылками на все сгенерированные файлы javascript. Чтобы использовать этот плагин, обновите webpack.config.js с этим —

const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
 module.exports = { entry: { bundle: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js'
- }
+ },
+ plugins: [
+ new HtmlWebpackPlugin()
+ ]
 };

После этого вы можете снова запустить команду сборки —

./node_modules/.bin/webpack

Теперь это создаст дополнительные index.html файл в dist каталог с соответствующими тегами script для включения bundle.js. Теперь его можно открыть напрямую в браузере, и он будет работать так же, как и раньше, за исключением того, что вам не нужно создавать его самостоятельно.

Чтобы сделать команду сборки короче, давайте создадим псевдоним внутри package.json так что вам нужно только ввести npm run build для объединения ваших файлов. Обновите свой package.json

{ "name": "hello-world", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "html-webpack-plugin": "^2.30.1", "webpack": "^3.11.0", "webpack-dev-server": "^2.11.1"
- }
+ },
+ "scripts": {
+ "build": "webpack"
+ }
 }

До сих пор webpack связывает файлы и завершает работу. Это хорошо, когда вы просто хотите связать и развернуть на своем локальном или удаленном сервере. Но во время разработки это может очень быстро разочаровать. Чтобы преодолеть это разочарование, вы будете использовать webpack-dev-server который постоянно следит за вашими файлами на предмет изменений и мгновенно обновляет страницу в браузере. Он также запускает сервер разработки внутри dist поэтому html-файл загружается с сервера, а не из файловой системы (на тот случай, если вы используете ajax в своем js, который не работает при открытии из файловой системы). Установите его с помощью —

npm install webpack-dev-server

Это запускает сервер разработки с dist как базовый каталог. URL-адрес по умолчанию http://localhost:8080. Открытие этого URL-адреса в вашем браузере загрузит index.html файл и журнал Hello World в консоли. Теперь, если вы обновите журнал консоли с Hello World к Hi World внутри src/index.js, webpack-dev-server автоматически перезагрузит браузер, и вы сможете увидеть новый вывод.

./node_modules/.bin/webpack-dev-server --content-base dist

Давайте добавим это также как псевдоним в package.json

{ "name": "hello-world", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "html-webpack-plugin": "^2.30.1", "webpack": "^3.11.0", "webpack-dev-server": "^2.11.1" }, "scripts": { "build": "webpack",
+ "dev": "webpack-dev-server --content-base dist"
 } }

Сейчас работает npm run dev начнет webpack-dev-server с автоматической перезагрузкой при изменении.

На данный момент вы еще не можете использовать синтаксис es6 в своем коде js. Добавим эту поддержку. Это будет сделано с помощью babel. Чтобы добавить поддержку Babel в процесс сборки, давайте сначала установим его. babel-loader потребуется babel-core быть установленным. И для поддержки синтаксиса es6/7/8/* вы добавите babel-preset-env. Запустите это в своем терминале в папке проекта —

npm install babel-core babel-loader babel-preset-env --save-dev

Сначала создайте .babelrc файл в каталоге проекта, чтобы Babel мог загрузить свою конфигурацию. Добавьте это в файл —

{ "presets": [["env", { "targets": { "browsers": ["Chrome >= 55"] } } ]]
}

Эта конфигурация используется преднамеренно, чтобы вы могли видеть связанный файл js в dist каталог и узнайте, как был транспилирован ваш код es6. Поскольку браузеры стали поддерживать все больше и больше функций es6, babel, вместо того, чтобы слепо транспилировать весь код, теперь разумно определяет, какие функции поддерживаются изначально, и не транспилирует эти части. Это уменьшает общий размер пакета.

Простейшая конфигурация, которую можно использовать вместо приведенной выше (если вас не волнует версия браузера), была бы такой:

Теперь давайте инструктировать webpack использовать babel для транспиляции js сначала файлы.

const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
 module.exports = { entry: `{ bundle: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, plugins: [ new HtmlWebpackPlugin()
- ]
+ ],
+ module: {
+ rules: [{
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: 'babel-loader'
+ }]
+ }
 };

Создать новый файл src/message.js и добавить это —

export default "Hello World";

Теперь измените src/index.js использовать простейшую функцию импорта es6 —

import message from './message'; console.log(message);

В приведенном выше коде используется синтаксис модуля es6. Сейчас работает npm run dev создаст обновленный пакет (хотя результат тот же), который вы можете протестировать в консоли браузера.

Это подводит итог первой части руководства, в которой вы настроили самый простой (серьезно самый простой) проект javascript, используя webpack для объединения с интеграцией babel для преобразования es6 в es5.

Часть 2

Теперь давайте перейдем ко второй части руководства, где мы настроим веб-пакет для импорта css файлы. Благодаря этому вы можете напрямую включать стили в свои файлы javascript.

Сначала изменим src/index.js чтобы показать некоторый текст на странице, а не просто войти в консоль.

import message from './message'; -console.log(message);
+const paragraph = document.createElement('p');
+paragraph.innerHTML = message;
+
+document.body.prepend(paragraph);

Это создает p тег с импортированным message как html и добавляет его на страницу.

Теперь давайте стилизуем это p тег с помощью css. Это требует css-loader а также style-loader. Установите его с помощью —

npm install css-loader style-loader --save-dev

Поддерживать css импорт файла, давайте обновим наш webpack.config.js с новым правилом, которое проверяет, имеет ли импортированный файл css расширение и анализирует его с помощью style-loader а также css-loader

const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { bundle: './src/index.js ' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, plugins: [new HtmlWebpackPlugin()], module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader'
+ }, {
+ test: /\.css$/,
+ exclude: /node_modules/,
+ use: [
+ {loader: 'style-loader'},
+ {loader: 'css-loader'}
+ ]
+ }]
 } };

Теперь создайте файл css src/index.css и стиль p ярлык —

Импортируйте этот файл css в src/index.css

import message from './message';
+import './index.css';
 const paragraph = document.createElement('p'); paragraph.innerHTML = message; document.body.prepend(paragraph);

Теперь перезапустите сервер разработки, используя npm run dev. Вы сможете увидеть, что страница теперь показывает Hello World в красном цвете. Если вы измените цвет с красного на синий в index.css, страница перезагрузится и будет виден новый стиль. Чтобы увидеть новый стиль без фактической перезагрузки страницы, измените команду dev server в package.json

{ "name": "hello-world", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "webpack",
- "dev": "webpack-dev-server --content-base dist"
+ "dev": "webpack-dev-server --content-base dist --hot"
 }, "keywords": [], "author": "" , "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-env": "^1.6.1", "css-loader": "^0.28.9", "html-webpack-plugin": "^2.30.1", "style-loader": "^0.20.2", "webpack": "^3.11.0", "webpack-de v-server": "^2.11.1" } }

Это включает горячую замену модуля в веб-пакете, который показывает новые изменения в вашем коде (в css или же js или любой файл, если webpack умеет его загружать) без полной перезагрузки страницы. Перезапустите сервер с помощью npm run dev и попробуй изменить цвет p в ссс. Вы заметите, что цвет страницы меняется без фактической перезагрузки страницы.

Если вы попытаетесь запустить команду сборки, npm run buildв dist каталог, вы заметите, что в нем нет созданных файлов css. Это связано с тем, что webpack добавляет стили в пакеты javascript в виде строк и применяет эти стили на странице, создавая style теги. Это нормально, когда вы развиваетесь. Но во время процесса развертывания всегда рекомендуется включать файлы css в head тег, чтобы внешний вид страницы не портился во время загрузки javascript. Чтобы исправить это, мы будем использовать extract-text-webpack-plugin который извлекает все импортированные css в свой собственный файл в процессе сборки. Перед этим давайте сначала настроим веб-пакет, чтобы понять development а также production режим.

const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); + const env = process.env.NODE_ENV || 'development';
+ const isDev = env === 'development';
+ const isProd = env === 'production';
 module.exports = { entry: { bundle: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, plugins: [new HtmlWebpackPlugin()], module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }, { test: /\.css$/, exclude: /node_modules/, use: [{loader: 'style-loader'}, {loader: 'css-loader'}] }] } };

И изменить package.json для запуска команды сборки в режиме производства и сервера разработки в режиме разработки.

{ "name": "hello-world", "version": "1.0.0", "description": "", "main": "index.js", "scripts": {
- "build": "webpack",
- "dev": "webpack-dev-server --content-base dist --hot"
+ "build": "NODE_ENV=production webpack",
+ "dev": "NODE_ENV=development webpack-dev-server --content-base dist --hot"
 }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-env": "^1.6.1", "css-loader": "^0.28.9", "extract-text-webpack-plugin": "^3.0.2", "html-webpack-plugin": "^2.30.1", "style-loader": "^0.20.2", "webpack": "^3.11.0", "webpack-dev-server": "^2.11.1" } }

Теперь установите extract-text-webpack-plugin с использованием —

npm install extract-text-webpack-plugin --save-dev

И обновить webpack.config.js

const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
 const env = process.env.NODE_ENV || 'development'; const isDev = env === 'development'; const isProd = env === 'production'; +const extractCss = new ExtractTextPlugin({
+ filename: 'index.css',
+ disable: isDev
+});
 module.exports = { entry: { bundle: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, plugins: [
- new HtmlWebpackPlugin()
+ new HtmlWebpackPlugin(),
+ extractCss
 ], module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }, { test: /\.css$/, exclude: /node_modules/,
- use: [
- {loader: 'style-loader'},
- {loader: 'css-loader'}
- ]
+ use: extractCss.extract({
+ use:[
+ {loader: 'css-loader'}
+ ],
+ fallback: 'style-loader'
+ })
 }] } };

Это отключает extractCss в режиме разработки, в этом случае style Тег используется для применения css. В производственном режиме, extractCss плагин извлекает все css из js пакеты в свои собственные файлы, которые названы в соответствии со значением filename используется при объявлении extractCss.

Сейчас работает npm run build создаст 3 файла в distbundle.js, index.css а также index.html.

добавим scss поддержка синтаксического анализа файла конфигурации webpack. Для этого вам понадобится sass-loader который в свою очередь нуждается node-sass. Установите их, используя —

npm install node-sass sass-loader --save-dev

Теперь обновите webpack.config.js чтобы вебпак знал, как обрабатывать импортированные файлы scss —

const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const env = process.env.NODE_ENV || 'development'; const isDev = env === 'development'; const isProd = env === 'production'; -const extractCss = new ExtractTextPlugin({
+const extractScss = new ExtractTextPlugin({
 filename: 'index.css', disable: isDev }); module.exports = { entry: { bundle: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, plugins: [ new HtmlWebpackPlugin(),
- extractCss
+ extractScss
 ], module: { rules: [{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }, {
- test: /\.css$/,
+ test: /(\.css|\.scss)$/,
 exclude: /node_modules/,
- use: extractCss.extract({
+ use: extractScss.extract({
 use:[
- {loader: 'css-loader'}
+ {loader: 'css-loader'},
+ {loader: 'sass-loader'}
 ], fallback: 'style-loader' }) }] } };

Теперь, чтобы проверить это, переименуйте index.css к index.scss и обновите его содержимое с помощью базовой вложенности scss —

body { p { color: red; }
}

Обновите импорт в index.js

import message from './message';
-import './index.css';
+import './index.scss';
 const paragraph = document.createElement('p'); paragraph.innerHTML = message; document.body.prepend(paragraph);

Проверьте это, запустив npm run dev и откройте URL-адрес в браузере.

Эта часть завершает использование импорта css а также scss файлы в js.

Часть 3

По мере того, как кодовая база проекта увеличивается в размерах, становится трудно поддерживать строгое руководство по написанию кода, если о нем не позаботятся на ранней стадии. Кроме того, по мере того, как все больше людей начинают вносить свой вклад в один проект, они могут привнести свой собственный стиль кодирования, что может привести к тому, что код в разных файлах будет выглядеть по-разному, и новым разработчикам становится сложно решить, какому стилю следовать. Эта проблема решается с помощью линтеров. Они помогают следовать единому строгому правилу написания кода. Линтеры в javascript показывают много полезных сообщений, таких как неиспользуемые переменные, отсутствующая точка с запятой (это может не быть проблемой в некоторых проектах), коды, превышающие максимально допустимую длину, и т. д. Давайте обновим наш проект, чтобы использовать eslint выдавать ошибку, когда не соблюдается определенное правило. Для этого нам нужно eslint а также eslint-loader. Установите их с помощью —

npm install eslint eslint-loader --save-dev

Теперь обновите webpack.config.js чтобы сообщить веб-пакету об использовании eslint-loader прежде чем пройти через babel-loader

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin'); const env = process.env.NODE_ENV || 'development';
const isDev = env === 'development';
const isProd = env === 'production'; const extractScss = new ExtractTextPlugin({ filename: 'index.css', disable: isDev
}); module.exports = { entry: { bundle: './src/index.js' }, output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js' }, plugins: [new HtmlWebpackPlugin(), extractScss], module: { rules: [{
+ enforce: 'pre',
+ test: /\.js$/,
+ exclude: /node_modules/,
+ use: 'eslint-loader'
+ }, {
 test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }, { test: /(\.css|\.scss)$/, exclude: /node_modules/, use: extractScss.extract({ use:[{loader: 'css-loader'}, {loader: 'sass-loader'}], fallback: 'style-loader' }) }] } };

Создать новый файл .eslintrc на верхнем уровне вашего проекта (наряду с package.json). В этом файле вы можете определить свои собственные правила и парсер для eslint следовать.

{ "parserOptions": { "ecmaVersion": 6, "sourceType": "module" }, "extends": "eslint:recommended"
}

ecmaVersion позволяет eslint распознавать функции ES6, sourceType: module позволяет использовать import а также export ключевые слова. По умолчанию правила для eslint. Так "extends": "eslint:recommended" рассказывает eslint использовать рекомендуемые правила по умолчанию.

В этот момент вы можете запустить npm run dev. В консоли вы увидите, что есть 2 ошибки одного типа:

4:19 error 'document' is not defined no-undef
7:1 error 'document' is not defined no-undef

Это говорит о том, что переменная document не определен(no-undef) где угодно, но все еще используется. Это можно исправить 2 способами. Чтобы исправить это, вам нужно использовать globals ключ в .eslintrc. Обновите свой .eslintrc

{ "parserOptions": { "ecmaVersion": 6, "sourceType": "module" },
- "extends": "eslint:recommended"
+ "extends": "eslint:recommended",
+. "globals": {
 "document": true } }

Это говорит eslint что переменная document является глобальным и будет предоставляться средой JS (в данном случае браузером). Теперь вы можете бежать npm run dev без какой-либо ошибки. Вы также можете добавить команду linting в package.json чтобы увидеть ошибку lint независимо от webpack. Обновлять package.json

{ "name": "hello-world", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "build": "NODE_ENV=production webpack",
- "dev": "NODE_ENV=development webpack-dev-server --content-base dist --hot"
+ "dev": "NODE_ENV=development webpack-dev-server --content-base dist --hot",
+ "lint": "eslint ./src --ext .js"
 }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "babel-core": "^6.26.0", "babel-loader": "^7.1.2", "babel-preset-env": "^1.6.1", "css-loader": "^0.28.9", "eslint": "^4.18.1", "eslint-loader": "^2.0.0", "extract-text-webpack-plugin": "^3.0.2", "html-webpack-plugin": "^2.30.1", "node-sass": "^4.7.2", "sass-loader": "^6.0.6", "style-loader": "^0.20.2", "webpack": "^3.11.0", "webpack-dev-server": "^2.11.1" }
}

Теперь вы можете бежать npm run lint в консоли и проверьте наличие ошибок линтинга независимо от того, связываете ли вы проект или нет. Это также можно использовать в git pre-commit hooks, чтобы запретить коммиты, если eslint выдает любую ошибку. eslint ./src --ext .js рассказывает eslint проверить наличие ошибок во всех файлах в src каталог с js расширение. Вы также можете добавить необязательный --fix опция этой команды, которая автоматически пытается исправить ошибки, чтобы вам не пришлось это делать.

Вы также можете добавить свои собственные правила в .eslintrc файл в соответствии с вашими требованиями. eslint:recommended опция не позволяет вам использовать console.log в вашем коде (рекомендуется использовать модуль ведения журнала). Вы можете добавить правило, чтобы сообщить eslint показать предупреждение в console.log утверждения вместо ошибки. Обновлять .eslintrc файл —

{ "parserOptions": { "ecmaVersion": 6, "sourceType": "module" }, "extends": "eslint:recommended", "globals": {
- "document": true
+ "document": true,
+ "console": true
- }
+ },
+ "rules": {
+ "no-console": 1
+ }
 }

"no-console": 1 рассказывает eslint чтобы показать предупреждение вместо ошибки. Другие значения 0 (выключить eslint для этого правила) и 2 (кинуть ошибку, если это правило нарушено). Есть несколько стандартных руководств по стилю JavaScript, которые используют многие компании (вместо стандартного eslint:recommended). Один из них — airbnb. руководство по стилю javascript который добавляет много общепринятых правил линтинга. Вы можете использовать это вместо текущего. Давайте добавим это в нашу конфигурацию. Требует установки доп. eslint-plugin-import зависимость. Установить eslint-config-airbnb-base и его зависимости с использованием —

npx install-peerdeps --dev eslint-config-airbnb-base

Теперь обновите .eslintrc

{
- "parserOptions": {
- "ecmaVersion": 6,
- "sourceType": "module"
- },
- "extends": "eslint:recommended",
+ "extends": "airbnb-base",
 "globals": { "document": true, "console": true }, "rules": { "no-console": 1 } }

airbnb-base имеет parserOptions внутри. Так что это было удалено. Теперь, когда вы бежите npm run devвы получите ошибку-

...hello-world/src/message.js
1:16 error Strings must use singlequote quotes

Это потому что airbnb-base имеет правило использовать одинарные кавычки для строк вместо двойных кавычек. Бег npm run lint с --fix опция автоматически изменится " к ' в src/message.js.

На этом использование eslint для обеспечения качества кода в вашем коде.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *