webpack4正式版发布也有一段时间了, 为了从实际中感觉变化, 因而以typescript, react, 结合以前翻译的一篇文章webpack-4.0更新日志(翻译), 搭建一个可供项目使用的框架.css
前往node
我是由另外一个项目升级过来的, 由于原项目没用babel, 直接以ts-loader转.react
原项目涉及到配置变化的库及版本webpack
原配置:nginx
// 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' 复制代码
果真跑不通, 符合心理预期!😂😂😂😂git
查看node_modules里面的react-hot-loader, 对比原项目node_modules的react-hot-loader, 文件结构改了很多, 看4.0.0的源码, 也再也不有webpack目录, 并且代码中有这么一段:es6
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), 省得挣扎!!github
按照react-hot-loader官方推荐作法以及demoweb
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.typescript
{
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调试生产环境代码, 虽然能跑, 不过, 这不是我想要的!
最后, 这部分的处理结果是把react-hot-loader/babel删除之! 再将tsx接受hot reload还原为旧式写法:
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插件
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')
})
复制代码
过程曲折, 还有一些问题没写上, 具体请参考项目...
若是你们有更好的解决方案, 也欢迎评论或提issue