diff --git a/package.json b/package.json
index 58d2a23..a1ff3b1 100644
--- a/package.json
+++ b/package.json
@@ -40,9 +40,11 @@
"less-loader": "^4.0.3",
"node-sass": "^4.5.2",
"postcss-loader": "^1.3.3",
+ "react-hot-loader": "^3.0.0-beta.6",
"sass-loader": "^6.0.3",
"style-loader": "^0.16.1",
"url-loader": "^0.5.8",
- "webpack": "^2.3.3"
+ "webpack": "^2.3.3",
+ "webpack-dev-server": "^2.4.2"
}
}
diff --git a/server.js b/server.js
index 7b11c41..844e0a7 100644
--- a/server.js
+++ b/server.js
@@ -1,6 +1,25 @@
const Koa = require('koa')
const send = require('koa-send')
const Router = require('koa-router')
+const webpack = require('webpack')
+const WebpackDevServer = require('webpack-dev-server')
+const config = require('./webpack.dev.config')
+
+const DEVPORT = 3001
+
+new WebpackDevServer(webpack(config), {
+ publicPath: config.output.publicPath,
+ hot: true,
+ quiet: false,
+ noInfo: true,
+ stats: {
+ colors: true
+ }
+}).listen(DEVPORT, 'localhost', function (err, result) {
+ if (err) {
+ return console.log(err)
+ }
+})
const app = new Koa()
const router = new Router()
@@ -9,10 +28,6 @@ router.get('/', async function (ctx) {
await send(ctx, 'demo/index.html')
})
-router.get('/app.js', async function (ctx) {
- await send(ctx, 'build/app.js')
-})
-
// 线上会使用压缩版本的React,而在开发的时候,我们需要使用react-with-addons来查看错误信息
// 所以这里把React和ReactDOM代理到本地未压缩的文件
router.get('**/react.min.js', async function (ctx) {
@@ -22,6 +37,10 @@ router.get('**/react-dom.min.js', async function (ctx) {
await send(ctx, 'demo/react-dom.js')
})
+router.get('**/*.js(on)?', async function (ctx) {
+ ctx.redirect(`http://localhost:${DEVPORT}/${ctx.path}`)
+})
+
app.use(router.routes())
app.listen(3000, function () {
diff --git a/src/App.js b/src/App.js
new file mode 100644
index 0000000..cfebdfa
--- /dev/null
+++ b/src/App.js
@@ -0,0 +1,19 @@
+import React, { Component } from 'react'
+
+import '_/styles/index.scss'
+
+class App extends Component {
+ constructor(props) {
+ super(props)
+
+ this.state = {}
+ }
+
+ render() {
+ return (
+
Hello world 125.
+ )
+ }
+}
+
+export default App
diff --git a/src/index.js b/src/index.js
index 3951382..28579cb 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,20 +1,7 @@
-import React, { Component } from 'react'
+import React from 'react'
import ReactDOM from 'react-dom'
-
-import '_/styles/index.scss'
-
-class App extends Component {
- constructor(props) {
- super(props)
-
- this.state = {}
- }
-
- render() {
- return (
- Hello world.
- )
- }
-}
+import App from './App'
ReactDOM.render(, document.getElementById('root'))
+
+module.hot && module.hot.accept()
diff --git a/webpack.dev.config.js b/webpack.dev.config.js
new file mode 100644
index 0000000..401d221
--- /dev/null
+++ b/webpack.dev.config.js
@@ -0,0 +1,113 @@
+const path = require('path')
+const webpack = require('webpack')
+const autoprefixer = require('autoprefixer')
+
+module.exports = {
+ devtool: 'cheap-module-source-map',
+ entry: {
+ // 需要编译的入口文件,增加了react-hot-loader的配置
+ app: [
+ 'react-hot-loader/patch',
+ 'webpack-dev-server/client?http://localhost:3001',
+ 'webpack/hot/only-dev-server',
+ './src/index.js',
+ ],
+ },
+ output: {
+ // 输出文件名称规则,这里会生成 'app.js'
+ filename: '[name].js',
+ publicPath: '/',
+ },
+
+ // 引用但不打包的文件
+ externals: { react: 'React', 'react-dom': 'ReactDOM' },
+
+ plugins: [
+ new webpack.HotModuleReplacementPlugin(),
+ ],
+
+ resolve: {
+ // 给src目录一个路径,避免出现'../../'这样的引入
+ alias: { _: path.resolve(__dirname, 'src') },
+ },
+
+ module: {
+ rules: [
+ {
+ test: /\.jsx?$/,
+ use: {
+ loader: 'babel-loader',
+
+ // 可以在这里配置babelrc,也可以在项目根目录加.babelrc文件
+ options: {
+
+ // false是不使用.babelrc文件
+ babelrc: false,
+
+ // webpack2 需要设置modules 为false
+ presets: [
+ ['es2015', { modules: false }],
+ 'react',
+ ],
+
+ // babel的插件
+ plugins: [
+ 'react-hot-loader/babel',
+ 'react-require',
+ 'transform-object-rest-spread',
+ ],
+ },
+ },
+ },
+
+ // 这是sass的配置,less配置和sass一样,把sass-loader换成less-loader即可
+ // webpack2 使用use来配置loader,并且不支持字符串形式的参数了,必须使用options
+ // loader的加载顺序是从后向前的,这里是 sass -> postcss -> css -> style
+ {
+ test: /\.scss$/,
+ use: [
+ { loader: 'style-loader' },
+
+ {
+ loader: 'css-loader',
+
+ // 开启了CSS Module功能,避免类名冲突问题
+ options: {
+ modules: true,
+ localIdentName: '[name]-[local]',
+ },
+ },
+
+ {
+ loader: 'postcss-loader',
+ options: {
+ plugins() {
+ return [
+ autoprefixer,
+ ]
+ },
+ },
+ },
+
+ {
+ loader: 'sass-loader',
+ },
+ ],
+ },
+
+ // 当图片文件大于10KB时,复制文件到指定目录,小于10KB转为base64编码
+ {
+ test: /\.(png|jpg|jpeg|gif)$/,
+ use: [
+ {
+ loader: 'url-loader',
+ options: {
+ limit: 10000,
+ name: './images/[name].[ext]',
+ },
+ },
+ ],
+ },
+ ],
+ },
+}