Typescript-react-webpack4 Начало работы и шаг в яму

TypeScript React.js CSS Babel
Typescript-react-webpack4 Начало работы и шаг в яму

предисловие

Прошло некоторое время с момента выхода официальной версии webpack 4. Чтобы почувствовать отличия от реальности, я использовал typescript, react и ранее переведенную статью.список изменений webpack-4.0 (перевод), чтобы построить структуру, которую можно использовать в проекте.

Статус проекта

github

идти к

предмет используется

  • webpack-4
  • typescript
  • react
  • react-router-4
  • component hot reload
  • async component
  • css-module(import .(s)css auto generate .(s)css.d.ts)
  • svg icon

быть добавленным

  • state management (Redux or Mobx)
  • UI lib (Element-React)
  • jest

Основные библиотеки и версии

  • webpack --------- 4.1.1
  • typescript -------- 2.7.2
  • react ------------ 16.2.0
  • react-router-dom -- 4.2.2
  • react-hot-loader --- 4.0.0
  • ......
  • node ------------- 8.9.4

яма

Я был обновлен из другого проекта, потому что исходный проект не использовал babel, а напрямую перенес его в ts-loader.

Исходный проект включает в себя библиотеку и версию изменения конфигурации

  • webpack --------- 4.1.1
  • react-hot-loader --- 3.1.3

Первоначальная конфигурация:

// tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "es2015",
    "moduleResolution": "node",
    ....
  }
}
// webpack.config.js
{
    test: /\.(ts(x?)|js(x?))$/,
    exclude: /node_modules/,
    rules: [
      {
        loader: 'react-hot-loader/webpack',
      },
      {
        loader: 'ts-loader',
        options: {
          transpileOnly: true
        }
    }
}
Module not found: Error: Can't resolve 'react-hot-loader/webpack' in '/Users/jackple/Documents/react/ts-react-webpack4'

Конечно, он не может бегать, что соответствует психологическим ожиданиям!😂😂😂😂

Проверьте реагирующий-горячий-загрузчик в node_modules.По сравнению с реагирующим-горячим-загрузчиком исходного проекта node_modules, структура файла сильно изменилась.Глядя на исходный код 4.0.0, больше нет каталога веб-пакета, и в коде есть такой абзац:

throw new Error('React Hot Loader: You are erroneously trying to use a Babel plugin ' + 'as a Webpack loader. We recommend that you use Babel, ' + 'remove "react-hot-loader/babel" from the "loaders" section ' + 'of your Webpack configuration, and instead add ' + '"react-hot-loader/babel" to the "plugins" section of your .babelrc file. ' + 'If you prefer not to use Babel, replace "react-hot-loader/babel" with ' + '"react-hot-loader/webpack" in the "loaders" section of your Webpack configuration. ');

Информация в приглашении не соответствует действительности, считается, что приглашение не было изменено, поэтому используйте babel (на самом деле егоREADMEТакже рекомендуется использовать babel), чтобы не бороться!!

Следуйте официальным рекомендациям react-hot-loader и demo

When using TypeScript, Babel is not required, but React Hot Loader will not work without it. Just add babel-loader into your Webpack configuration, with React Hot Loader plugin.

{
  test: /\.tsx?$/,
  use: [
    {
      loader: 'babel-loader',
      options: {
        babelrc: true,
        plugins: ['react-hot-loader/babel'],
      },
    },
    'ts-loader', // (or awesome-typescript-loader)
  ],
}

You also have to modify your tsconfig.json:

// tsconfig.json
{
  "module": "commonjs",
  "target": "es6"
}
// xxx.tsx
import { hot } from 'react-hot-loader'
...
export default hot(module)(Component)
  1. Первый — это react-hot-loader/babel, независимо от того, настроен ли он в соответствии с официальной рекомендацией или написан в .babelrc, оба вышеперечисленных добавляются с оценкой окружающей среды, среда разработки не вызывает проблем, но упакованный код рабочей среды выглядит странный:
...
default = i, u = r(4).
default, s = r(4).leaveModule, u && (u.register(l, "Error", "/Users/jackple/Documents/react/ts-react-webpack4/src/components/Error/index.tsx"), u.register(i, "default", "/Users/jackple/Documents/react/ts-react-webpack4/src/components/Error/index.tsx"), s(e))
}).call(this, r(12)(e))
...

Как ни посмотри, а смысла нет!Почему у меня выходит путь к локальному исходному файлу!Открой nginx локально для отладки кода продакшн среды,хоть он и может запускаться,но это не то что я хочу!

Наконец, результатом этой части обработки является удаление react-hot-loader/babel!Затем tsx принимает горячую перезагрузку и восстанавливает старый способ написания:

import { AppContainer } from 'react-hot-loader'

import AppRouter from './router'

const render = Component => {
    ReactDOM.render(
        <AppContainer>
            <Component />
        </AppContainer>,
        document.getElementById('app') as HTMLElement
    )
}

render(AppRouter)

// Hot Module Replacement API
if (module.hot) {
    module.hot.accept(['router'], () => {
        import('./router').then(mod => render(mod.default))
    })
}

  1. Кроме того, для того, чтобы сотрудничать с расщеплением кода (динамический импорт) WebPack4, вам необходимо установить модуль в TSConfig.json в ESNext (в основном для предотвращения Impractcript из импорта составления), я не знаю, если это моя настройка Обозначена ошибка, и отображается следующая ошибка:
ERROR in ./src/index.tsx
Module build failed: SyntaxError: 'import' and 'export' may only appear at the top level (14:8)

  12 | if (module.hot) {
  13 |     module.hot.accept(['router'], () => {
> 14 |         import('./router').then(mod => render(mod.default));
     |         ^
  15 |     });
  16 | }

Чтобы не сказать о хорошей поддержке грамматики IMPORT, добавьте плагин Syntax-Dynamic-Import Babel.

  1. извлечение css-модуля
new ExtractTextPlugin({
    filename: assetsPath('css/[name].[contenthash].css')
})
bootstrap:74 Uncaught (in promise) TypeError: Cannot read property 'call' of undefined
    at i (bootstrap:74)
    at Object.31 (index.css:1)
    at i (bootstrap:74)
    at Object.32 (index.css?f62f:2)
    at i (bootstrap:74)
    at Object.52 (index.tsx:3)
    at i (bootstrap:74)
    at index.tsx:9
    at <anonymous>

Задача извлечения css асинхронных компонентов заканчивается извлечением всего css в один файл, а именно:

new ExtractTextPlugin({
    allChunks: true,
    filename: assetsPath('css/[name].[contenthash].css')
})

Процесс мучительный, и есть еще некоторые проблемы, которые не были написаны, пожалуйста, обратитесь к деталямпроект...

Если у вас есть лучшее решение, пожалуйста, прокомментируйте илиподнимать вопрос