предисловие
Прошло некоторое время с момента выхода официальной версии 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)
- Первый — это 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))
})
}
- Кроме того, для того, чтобы сотрудничать с расщеплением кода (динамический импорт) 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.
- извлечение 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')
})
Процесс мучительный, и есть еще некоторые проблемы, которые не были написаны, пожалуйста, обратитесь к деталямпроект...
Если у вас есть лучшее решение, пожалуйста, прокомментируйте илиподнимать вопрос