Как заставить webpack typcript реагировать на конфигурацию webpack-dev-server для автоматической сборки и перезагрузки страницы
Мое намерение состоит в том, чтобы иметь такую структуру каталогов:
- /my-project/
-- /src/ (here are all .tsx files located)
-- /dist/
- index.html
- /build/
-bundle.js
-- /node_modules/
-- package.json
-- tsconfig.json
-- webpack.config.js
Итак, я хочу иметь свой index.html, который создается вручную в подкаталоге / dist, и внутри него я хочу иметь подкаталог /build, куда идет app.js, созданный webpack.
И я хочу, чтобы при сохранении некоторого файла.tsx, находящегося в моем / src dir webpack, автоматически перестраивался app.js, а webpack-dev-server автоматически отражал изменения.
мой package.json
выглядит так:
{
"name": "my-project",
"version": "1.0.0",
"description": "My first React App",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server --content-base ./dist --hot --inline --colors --port 3000 --open",
"build": "webpack --config webpack.config.js --watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "AndreyKo",
"license": "ISC",
"devDependencies": {
"@types/react": "^0.14.54",
"@types/react-dom": "^0.14.19",
"jquery": "^3.1.1",
"source-map-loader": "^0.1.5",
"ts-loader": "^1.3.0",
"typescript": "^2.1.4",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2"
},
"dependencies": {
"react": "^15.4.1",
"react-dom": "^15.4.1"
}
}
мой webpack.config.js
:
module.exports = {
entry: "./src/index.tsx",
output: {
filename: "app.js",
publicPath: "/dist/",
path: "./dist/build/"
},
dev_tool: "source-map",
resolve: {
extensions: ['', '.webpack.js', '.web.js', '.ts', '.tsx', '.js']
},
module: {
loaders: [
{test: /\.tsx?$/, loader: 'ts-loader'}
],
preloaders: [
{test: /\.js$/, loader: 'source-map-loader'}
]
}
}
мой index.html
:
<!DOCTYPE html>
<html>
<body>
<div id="app-container"></div>
</body>
<script src="./build/app.js"></script>
</html>
И мой index.tsx
файл выглядит так:
import * as jQuery from 'jquery';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
function appOutput() {
ReactDOM.render(<div>Hello, we are talking from React!</div>, document.getElementById("app-container"));
}
appOutput();
Я сделал команды для терминала:
npm run build
npm run start
Итак, app.js был создан, и webpack-dev-server начал работать и открыл страницу в браузере. Все идет хорошо, безусловно. Но когда я изменяю текст в моем index.tsx и сохраняю этот файл, ничего не меняется, я пытался обновить страницу браузера, текст остается прежним, а app.js не перестраивается. Чтобы внести изменения в текст, мне нужно вручную перекомпилировать app.js с webpack вручную из терминала, выполнив команду "npm run build".
Как улучшить рабочий процесс, чтобы изменения в моей папке / src автоматически отражались в моем файле dist /build / app.js без необходимости его перестройки вручную?
2 ответа
Здесь я приведу более полный и (что более важно) более правильный ответ для любого, кто может наткнуться на конфигурацию среды разработки для разработки activ-webpack-typcript. Каким-то образом чтение документации было недостаточно хорошо для меня, и мне пришлось потратить больше одного дня, чтобы заставить его работать.
Поэтому я хотел получить структуру каталогов, в которой связанные файлы javascript лежат на один уровень глубже, чем файл html index.html. Посмотрите на начальный пост для полной структуры каталогов.
И как разработчик я хотел, чтобы при изменении какого-либо файла.tsx в папке / src мои изменения были отражены в браузере, а также нам нужно перекомпилировать связанный файл.js. Для этих целей в блоке scripts файла package.json проекта создаются два скрипта:
"scripts": {
"start": "webpack-dev-server --content-base ./dist --hot --inline --colors --port 3000 --open",
"build": "webpack --config webpack.config.js --watch",
}
Первый запускает webpack-dev-server, предоставляя ему корневой каталог / dist для обслуживания и ключи --hot --inline, чтобы автоматически перезагрузить страницу браузера и избавиться от ненужного iframe. При запуске webpack-dev-server есть также определенная опция --port и auto page --open.
Вторая команда предназначена для автоматической перекомпоновки прилагаемого app.js с помощью веб-пакета благодаря ключу --watch.
И чтобы эти команды работали должным образом, веб-пакет должен быть правильно настроен в файле webpack.config.js. И самая деликатная часть для меня (и для многих других, как я позже увидел) - это правильный путь, настройки publicPath и имени файла блока вывода. В моем первоначальном посте в publicPath произошла ошибка, из-за которой мой webpack-dev-server не работал.
Не работает выходной блок:
output: {
filename: "app.js",
publicPath: "/dist/",
path: "./dist/build/"
}
Блок вывода, который работает:
output: {
filename: "app.js",
publicPath: "/build/",
path: "./dist/build/"
}
Свойство publicPath используется webpack-dev-server для обновления страницы браузера, и оно должно быть установлено в каталог, где ваши скомпилированные файлы.js лежат относительно каталога корневого сервера, который установлен ключом --content-base в моем начале скрипт и ссылается на./dist внутри моего проекта. Поэтому правильное значение - / build /, а не / dist /.
Свойства пути и имени файла используются веб-пакетом и командой, куда поместить и как назвать связанный файл.js. В моем случае файл./dist/build/app.js будет создан.
Еще одна вещь, которая, безусловно, присутствует в документах, но я хотел бы отметить здесь, что когда я сохраняю некоторый файл.tsx после того, как я запустил свой webpack-dev-server со своим стартовым скриптом, но не выполнил команду build (которая делает изменения в веб-пакете) Я получаю обновленные результаты в браузере, но мой файл app.js в комплекте не изменяется. И это потому, что webpack-dev-server обновляет только копию в памяти встроенного файла.js, а не сам файл. Для синхронизации нам нужно перестроить пакет с помощью веб-пакета.
Если я хочу, чтобы мой связанный файл.js оставался синхронизированным со страницей браузера, мне нужно внести изменения в просмотр веб-пакетов, а веб-пакет-dev-server выполнить "горячую" перезагрузку страницы, поэтому я запускаю сценарии "start" и "build". Но я не могу запустить их оба из одной командной строки на моем компьютере с Windows, поэтому я запускаю каждый из них по отдельности с помощью:
Это действительно только для окон!
start npm run start && start npm run build
И ради своих пальцев я поместил эту строку в файл run.bat, который помещается в папку проекта. Теперь я могу просто открыть терминал Windows в редакторе VSCode и выполнить команду "Выполнить" там.
Это все на данный момент.
В текущей версии инструментария webpack необходимо установить webpack-cli (npm install webpack-cli --save-dev) и использовать:
webpack-cli serve --config ./webpack.config.js
Итак, мне удалось решить мою проблему, хотя и не идеально.
Похоже, что это зависит от ОС и другой среды, я хочу быть точным: моя ОС - windows7, мой редактор - VS Code.
Прежде всего хочу отметить, что моя установка работает так, как мне нужно, без каких-либо настроек.
Но это не работает, когда я запускаю команды сборки и запуска с терминала VS Code.
Чтобы сделать это, мне нужно было открыть два отдельных окна терминала, и в первом из них я запустил мой скрипт сборки, а во втором мой скрипт запуска:
first Terminal > npm run build
second Terminal > npm run start
Еще один способ сделать это прямо из терминала VS Code - ввести там такую команду:
start npm run start && start npm run build
который делает абсолютно то же самое - открывает два окна терминала и запускает команды npm в этих окнах.
Наконец, я создал файл run.bat, куда я поместил эту строку, и теперь я могу просто открыть свой проект в VS Code и в терминале запустить команду "run", и webpack и webpack-dev-server начнут наблюдать за изменениями.
Вот и все. Если есть лучшие способы, пожалуйста, укажите мне, я открыт для более элегантных способов решить эту проблему.