webpack4正式版發佈也有一段時間了, 爲了從實際中感覺變化, 因而以typescript, react, 結合以前翻譯的一篇文章webpack-4.0更新日誌(翻譯), 搭建一個可供項目使用的框架.css
前往node
原配置:react
// 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'
果真跑不通, 符合心理預期!????webpack
查看node_modules裏面的react-hot-loader, 對比原項目node_modules的react-hot-loader, 文件結構改了很多, 看4.0.0的源碼, 也再也不有webpack目錄, 並且代碼中有這麼一段:nginx
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), 省得掙扎!git
按照react-hot-loader官方推薦作法以及demoes6
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)
... 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調試生產環境代碼, 雖然能跑, 不過, 這不是我想要的!github
最後, 這部分的處理結果是把react-hot-loader/babel刪除之! 再將tsx接受hot reload還原爲舊式寫法:web
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)) }) }
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插件typescript
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>
過程曲折, 還有一些問題沒寫上, 具體請參考項目...
若是你們有更好的解決方案, 也歡迎評論或提issue