Как заставить 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 начнут наблюдать за изменениями.

Вот и все. Если есть лучшие способы, пожалуйста, укажите мне, я открыт для более элегантных способов решить эту проблему.

Другие вопросы по тегам