折腾:
【已解决】ReactJS-AdminLTE中如何调试和哪部分代码是首页的源码
和:
后,去修改了源文件
比如:
ReactJS-AdminLTE/src/pages/dashboardV1/js/components/navigation-menu.js
改个中文文字:
然后虽然可以看到命令行中:
webpack: Compiling
但是实际上页面:
还是没有更新:
目前此处的配置是:
/ReactJS-AdminLTE/server.js
let webpackListenPort = 3000; var webpack = require(‘webpack’); var WebpackDevServer = require(‘webpack-dev-server’); var config = require(‘./webpack.config’); new WebpackDevServer(webpack(config), { publicPath: config.output.publicPath, hot: true, inline: true, historyApiFallback: true }).listen(webpackListenPort, ‘localhost’, function (err, result) { if (err) { console.log(err); } console.log(`Listening at localhost:${webpackListenPort}`); }); |
ReactJS-AdminLTE/webpack.config.js
plugins: [ new webpack.HotModuleReplacementPlugin(), module: { noParse: [ //new RegExp(node_dir + ‘/react’), new RegExp(lib_dir + ‘./react-dom.js’) ], loaders: [ { test: /\.jsx?$/, loaders: [‘react-hot’], include: path.join(__dirname, ‘public’), exclude: /(node_modules|bower_components)/ }, |
webpack-dev-server 配置
[webpack] webpack-dev-server介绍及配置 – <!–hhhyaaon–> – 博客园
webpack-dev-server使用方法,看完还不会的来找我~ – JSer – SegmentFault
关于 webpack 和 webpack-dev-server 配置的个人小结 – 前端 – 掘金
Webpack-Chinese-Translation/README.md at master · jackyon/Webpack-Chinese-Translation
怀疑是不是目前只能支持到依赖的js文件的第一层,第一层所引用的其他js就无法解析到了?
结果:
第一层都没法通知到。
总之,现在的现象就是:
js文件更新后,webpack是可以检测到,并重新编译compile的
但是浏览器端,并没有被通知到。
webpack compile but not hot reload
Hot Reload not responding to changes on components · Issue #378 · vuejs-templates/webpack
需要加上:
content-base
参数?
用webpack-dev-server有两种方式:
命令行CLI中运行:
webpack-dev-server 加上参数
比如之前的:
webpack-dev-server –open –inline —hot
或者是:
调用接口WebpackDevServer
且还需要webpack.config.js中加上额外的配置。
去尝试加:
‘webpack/hot/dev-server’, ‘webpack-dev-server/client?http://localhost:8080/’, |
到
webpack.config.js的entry中:
但是感觉好像语法不对:
entry是个list
我这里entry是个dict
webpack-hmr-starter-dev-server-api/server.js at master · ahfarmer/webpack-hmr-starter-dev-server-api
hot module replacement with webpack
抽空好好看看webpack的配置:
看了看之前正常能工作的Preact项目中的写法
src/index.js
// in development, set up HMR: if (module.hot) { //require(‘preact/devtools’); // turn this on if you want to enable React DevTools! module.hot.accept(‘./container/app’, () => requestAnimationFrame(init) ); } |
之后能在浏览器中看到:
dev-server.js?30c5:49 [HMR] Waiting for update signal from WDS…
ReactJS-AdminLTE hmr not work
Can’t get it to work with ReactJS-AdminLTE · Issue #1380 · facebookincubator/create-react-app
Can’t get it to work with ‘react create app’ · Issue #34 · booleanhunter/ReactJS-AdminLTE
Possible fix for #34 · booleanhunter/ReactJS-AdminLTE@d6375a4
webpack-dev-server hmr not work
webpack hot reload doesnt work · Issue #741 · webpack/webpack-dev-server
Hot module / hrm not working anymore? · Issue #862 · webpack/webpack-dev-server
抽空试试:
entry: { 。。。 ‘vendor’: [ ‘react-hot-loader/patch’, ‘webpack-dev-server/client?http://0.0.0.0:9000’, |
和:
javascript – Webpack dev server hot mode not working – Stack Overflow
中的:
<script src=”http://localhost:8080/webpack-dev-server.js”></script>
Hot Reload not responding to changes on components · Issue #378 · vuejs-templates/webpack
关于 webpack 和 webpack-dev-server 配置的个人小结 – 前端 – 掘金
Webpack’s HMR & React-Hot-Loader — The Missing Manual
解释的很详细,抽空好好看看。
然后给:
/ReactJS-AdminLTE/views/dashboard.html
加上:
<script src=”http://localhost:3000/webpack-dev-server.js”></script> |
然后好像WDS的HMR真的生效了?
[WDS] Hot Module Replacement enabled. webpack-dev-server.js:1
然后去修改文字,结果console输出了
Recompiling
但是结果还是没有变化:
对于此处的webpack 1.x(而不是最新的2.x)来说,去试试:
添加:
config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${webpackListenPort}/`); |
注意,此处不是:
config.entry.app.unshift
否则会提示不支持unshift,因为此处没有app,而是vendors:
即:
ReactJS-AdminLTE/webpack.config.js
entry: { dashboardV1: ‘./src/pages/dashboardV1/js/dashboard’, widgets: [‘./src/pages/widgets-page/js/widgets-page’], timeline: ‘./src/pages/timeline-page/js/timeline-page’, generalUIElements: ‘./src/pages/ui-elements-page/general/js/page-ui-elements’, vendors: [‘react’, ‘react-dom’, ‘jquery’, ‘velocity-animate’, ‘jqueryUi’, ‘bootstrap’, ‘moment’, ‘bootstrapDatepicker’], chartVendors: [‘jquery’, ‘raphael’, ‘morris’, ‘jvectormap’, ‘jvectormapWorld’], // ‘webpack/hot/dev-server’, // ‘webpack-dev-server/client?http://localhost:8080/’, }, |
结果:
虽然hot update但是内容还是没变:
(源码的内容已改为:HMR继续测试)
通过配置文件:
ReactJS-AdminLTE/webpack.config.js
加上:
entry: { 。。。 vendors: [ ‘webpack/hot/dev-server’, ‘webpack-dev-server/client?http://localhost:3000/’, ‘react’, 。。。 ], 。。。 }, |
试试:
(后续贴的图)修改了内容后,terminal终端和Chrome的console都会看到
Recompiling…
然后终于可以HMR可以刷新页面,显示最新修改后的内容了:
源码内容是:
【总结】
此处想要实现inline+HMR,即:
当代码有改动后,自动重新编译,然后自动打包输出,且浏览器自动热更新,自动去刷新页面。
对于此需求,对应着webpack中,好像就是两个属性:inline和HMR。
对应的实现方式,webpack的官网其已经解释的其实很清楚了。
注:
关于inline+HRM的webpack官网:
1.x
此处ReactJS-AdminLT的webpack用的是1.14.1,所以参考的是1.x的文档:
2.x
最新版本的是2.x,对应文档为:
此处主要解释1.x的做法:
【inline模式】
先解释inline模式的效果:
(1)状态信息会输出到console命令行(此处是Mac的中iTerm),简要的信息会输出到浏览器(此处的是Mac的Chrome)的console命令行
(2)app内部的URL变化后,会反应到浏览器中的url地址
再说如何去实现:
【webpack中的inline模式】
对于Webpack 1.x来说,3种方式:
(1)命令行模式:
webpack-dev-server –inline |
自动帮你加上对应的配置。
(2)webpack.config.js中加上配置:
devServer: { inline: true } |
【Node.js API中的inline模式】
先解释,什么是Node.js API:
此处指的是:webpack-dev-server
其是一个基于Node.js的(还是Express的)服务器?
总之就是和类似于这样的代码:
new WebpackDevServer() |
有关系,指的是,从API接口的代码中,如何实现inline。
再说:
由于webpack-dev-server中没法访问webpack的配置,所以webpack-dev-server中是没有inline模式的选项控制的。所以用户必须手动的去加webpack-dev-server的client客户端的入口entry到webpack的配置中。具体做法:
把
webpack-dev-server/client?http://«path»:«port»/ |
加到所有的入口中。
官网示例代码:
var config = require(“./webpack.config.js”); config.entry.app.unshift(“webpack-dev-server/client?http://localhost:8080/”); var compiler = webpack(config); var server = new WebpackDevServer(compiler, {…}); server.listen(8080); |
【HTML中的inline】
也可以通过把:
<script src=”http://localhost:8080/webpack-dev-server.js”></script> |
加入到HTML中,去实现inline模式。
【HMR热更新】
想要实现热更新的话,直接在CLI命令行中加上参数:
webpack-dev-server –hot |
即可。其内部会把HotModuleReplacementPlugin加到webpack的配置中。
【inline模式+HMR】
如果实现了inline+HMR,就是之前所希望的效果:
然后在浏览器的console中会看到类似于:
[HMR] Waiting for update signal from WDS… [WDS] Hot Module Replacement enabled. |
的输出。
其中:
[HMR]开头的:来自webpack/hot/dev-server,HMR=Hot Module Replacement
[WDS]开头的:来自webpack-dev-server,WDS=Webpack Dev Server
而想要实现inline+HMR,也有多种方式:
最简单的去实现 inline+HMR的方式,就是:
【命令行CLI中使用inline+HMR】
webpack-dev-server –inline –hot |
即可,其自动的内部帮你把相关的:
webpack/hot/dev-server |
加到webpack的entry配置中。
且要注意设置正确的output.publicPath,否则HMR热更新无法加载对应的打包出来的chunks文件。
【Node.js API中实现 inline+HMR】
要做三件事:
把webpack/hot/dev-server加到配置文件的entry中
把new webpack.HotModuleReplacementPlugin()加到配置文件中
把配置属性hot: true加到webpack-dev-server中
举例:
var config = require(“./webpack.config.js”); config.entry.app.unshift(“webpack-dev-server/client?http://localhost:8080/”, “webpack/hot/dev-server”); var compiler = webpack(config); var server = new webpackDevServer(compiler, { hot: true … }); server.listen(8080); |
解释完毕之后,附上此处ReactJS-AdminLTE的实际的设置和解释:
其中,关于ReactJS-AdminLTE的代码调用逻辑,此处不再赘述,详见:
此处只接着说关于webapck的inline+HMR如何设置。
ReactJS-AdminLTE/server.js
var http = require(“http”); //1 var url = require(“url”); //2 var express = require(“express”); var consolidate = require(‘consolidate’); var handlebars = require(‘handlebars’); var bodyParser = require(‘body-parser’); var routes = require(‘./routes’); var app = express(); let appPort = 8000; app.set(‘views’, ‘views’); //Set the folder-name from where you serve the html page. ] app.set(‘view engine’, ‘html’); app.engine(‘html’, consolidate.handlebars); app.use(express.static(‘./public’)); //Set the folder from where you serve all static files like images, css, javascripts, libraries etc app.use(bodyParser.urlencoded({ extended: true })); var portNumber = process.argv[2] || appPort; http.createServer(app).listen(portNumber, function(){ console.log(‘Server listening at port ‘+ portNumber); routes.initialize(app); }); let wdsListenPort = 3000; var webpack = require(‘webpack’); var WebpackDevServer = require(‘webpack-dev-server’); var config = require(‘./webpack.config’); // add HMR module into entry point config.entry.vendors.unshift(`webpack/hot/dev-server`); // add inline mode module into entry point config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${wdsListenPort}/`); //config.entry.vendors.unshift(`webpack/hot/dev-server`, `webpack-dev-server/client?http://localhost:${wdsListenPort}/`); // add HMR plugin let hmrModule = new webpack.HotModuleReplacementPlugin(); // console.log(hmrModule); // HotModuleReplacementPlugin {} // console.log(`server.js: config.plugins=${JSON.stringify(config.plugins)}`); // config.plugins.push(hmrModule); // add to list end config.plugins.unshift(hmrModule); // add to list first // console.log(`server.js: config.plugins=${JSON.stringify(config.plugins)}`); var compiler = webpack(config); // more info refer http://webpack.github.io/docs/webpack-dev-server.html new WebpackDevServer(compiler, { // contentBase: ‘public/dist’, publicPath: config.output.publicPath, // Enable special support for Hot Module Replacement // Page is no longer updated, but a “webpackHotUpdate” message is sent to the content // Use “webpack/hot/dev-server” as additional module in your entry point // Note: this does _not_ add the `HotModuleReplacementPlugin` like the CLI option does. // Note: after test has verified: if not add hot: true here, HMR also work hot: true, // WebpackDevServer() API NO inline option // inline: true, // Set this as true if you want to access dev server from arbitrary url. // This is handy if you are using a html5 router. historyApiFallback: true, // proxy: { // “*” : `http://localhost:${wdsListenPort}` // <– Proxy everthing! // } }).listen(wdsListenPort, ‘localhost’, function (err, result) { if (err) { console.log(err); } console.log(`WDS Listening at localhost:${wdsListenPort}`); }); |
解释:
(1)代码整体逻辑
上半段是设置app的代码,包括端口号8000
下半段时设置WDS=WebpackDevServer的,对应端口号是3000
其中的:
var config = require(‘./webpack.config’); // add HMR module into entry point config.entry.vendors.unshift(`webpack/hot/dev-server`); // add inline mode module into entry point config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${wdsListenPort}/`); |
(2)含义:
通过webpack/hot/dev-server去添加HMR的,实现热更新的
通过webpack-dev-server/client?http://localhost:3000,实现inline模式的
(3)上面这两句,其实可以写成一句:
config.entry.vendors.unshift(`webpack/hot/dev-server`, `webpack-dev-server/client?http://localhost:${wdsListenPort}/`); |
且这两个配置等价于:
ReactJS-AdminLTE/webpack.config.js
中的:
entry: { dashboardV1: ‘./src/pages/dashboardV1/js/dashboard’, 。。。 vendors: [ // ‘webpack/hot/dev-server’, // ‘webpack-dev-server/client?http://localhost:3000/’, ‘react’, ‘react-dom’, 。。。 ], chartVendors: [‘jquery’, ‘raphael’,。。。], }, |
其中:
entry下面的是各个入口,表示要输入的文件,用于转换后输出到output的path。
entry中的webpack/hot/dev-server和webpack-dev-server/client?http://localhost:3000/和上面的WDS的API代码中的写法,效果是一样的。
(4)HotModuleReplacementPlugin
// add HMR plugin let hmrModule = new webpack.HotModuleReplacementPlugin(); config.plugins.unshift(hmrModule); // add to list first |
这部分是通过代码方式去添加HotModuleReplacementPlugin
其实等价于:
ReactJS-AdminLTE/webpack.config.js
中的:
plugins: [ new webpack.HotModuleReplacementPlugin(), … ], |
两种写法都可以,效果一样。
ReactJS-AdminLTE/webpack.config.js
。。。 var webpack = require(‘webpack’); var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin; var path = require(“path”); 。。。 var config = { resolve: { 。。。 plugins: [ // new webpack.HotModuleReplacementPlugin(), // moved this in server.js 。。。 new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/) // to not to load all locales ], devtool: ‘cheap-module-source-map’, entry: { dashboardV1: ‘./src/pages/dashboardV1/js/dashboard’, 。。。 vendors: [ // ‘webpack/hot/dev-server’, // ‘webpack-dev-server/client?http://localhost:3000/’, ‘react’, ‘react-dom’, ‘jquery’, 。。。 ], chartVendors: [‘jquery’, ‘raphael’, 。。。], }, output: { path: path.join(__dirname, “public”), // path: path.resolve(__dirname, “public”), filename: “dist/js/[name].bundle.js”, libraryTarget: “umd”, umdNamedDefine: true, }, module: { 。。。 loaders: [ { test: /\.jsx?$/, loaders: [‘react-hot’], include: path.join(__dirname, ‘public’), exclude: /(node_modules|bower_components)/ }, 。。。 ] } // devServer: { // hot: true, // inline: true // } }; module.exports = config; 。。。 |
说明:
(1)此处没有用到devServer的配置,而且据说对于此处用server.js中WDS的API的写法的话,devServer即使设置了也不起效果。
(2)如前所述,entry中的webpack/hot/dev-server和webpack-dev-server/client?http://localhost:3000/和代码中的:
var config = require(‘./webpack.config’); // add HMR module into entry point config.entry.vendors.unshift(`webpack/hot/dev-server`); // add inline mode module into entry point config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${wdsListenPort}/`); |
是一样的。
(3)如前所述,plugins中的new webpack.HotModuleReplacementPlugin(),和代码中的:
let hmrModule = new webpack.HotModuleReplacementPlugin(); config.plugins.unshift(hmrModule); // add to list first |
效果是一样的。
/ReactJS-AdminLTE/views/dashboard.html
<!– AdminLTE App –> <script src=”https://code.jquery.com/jquery-3.1.1.min.js” integrity=”sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=” crossorigin=”anonymous”></script> <!– <script src=”dist/js/app.js”></script> –> <!– <script src=”dist/js/pages/dashboard.js”></script> <script src=”dist/js/demo.js”></script> –> <!– <script src=”/dist/js/vendors.js”></script> <script src=”/dist/js/chartVendors.bundle.js”></script> <script src=”/dist/js/dashboardV1.bundle.js”></script> –> <!–Use this only in development, while using React Hot Loader –> <!– <script src=”http://localhost:3000/dist/js/app.js”></script> –> <!– Note here 3000 is WDS port, not app port !!! –> <script src=”http://localhost:3000/dist/js/vendors.js”></script> <script src=”http://localhost:3000/dist/js/chartVendors.bundle.js”></script> <script src=”http://localhost:3000/dist/js/dashboardV1.bundle.js”></script> <!– <script src=”http://localhost:3000/webpack-dev-server.js”></script> –> </body> </html> |
说明:
(1)此处是使用了development开发模式+HMR,所以注释掉了之前的代码:
<!– <script src=”/dist/js/vendors.js”></script> <script src=”/dist/js/chartVendors.bundle.js”></script> <script src=”/dist/js/dashboardV1.bundle.js”></script> –> |
和:
<!– <script src=”http://localhost:3000/dist/js/app.js”></script> –> |
否则浏览器的console中会报错找不到dist/js/app.js
然后加上WDS(端口3000)的地址:
<script src=”http://localhost:3000/dist/js/vendors.js”></script> <script src=”http://localhost:3000/dist/js/chartVendors.bundle.js”></script> <script src=”http://localhost:3000/dist/js/dashboardV1.bundle.js”></script> |
且这几个文件:
dist/js/vendors.js
dist/js/chartVendors.bundle.js
dist/js/dashboardV1.bundle.js
对应着:
ReactJS-AdminLTE/webpack.config.js中的entry中的:vendors,chartVendors,dashboardV1
(2)webpack-dev-server.js
此处的:
<script src=”http://localhost:3000/webpack-dev-server.js”></script> |
的写法是和
/ReactJS-AdminLTE/server.js
中的:
config.entry.vendors.unshift(`webpack-dev-server/client?http://localhost:${wdsListenPort}/`); |
是等价的。
同理和:
ReactJS-AdminLTE/webpack.config.js
中的:
entry的vendors中的’webpack-dev-server/client?http://localhost:3000/’
entry: { 。。。 vendors: [ ‘webpack-dev-server/client?http://localhost:3000/’, |
是等价的。
【后记】
后来参考:
webpack-hmr-starter-dev-server-api/server.js at master · ahfarmer/webpack-hmr-starter-dev-server-api
-》
webpack dev server · webpack/docs Wiki
去设置:
ReactJS-AdminLTE/server.js
new WebpackDevServer(compiler, { stats: { colors: true, } |
然后效果是:
Mac的Terminal中,显示的内容是彩色的:
正常内容是白色的,输出文件是绿色的,警告是黄色的:
也知道了:
对于WebpackDevServer的API的所有参数,都可以去:
webpack dev server · webpack/docs Wiki
找到具体的解释,和看看到底支持哪些参数。
转载请注明:在路上 » 【已解决】ReactJS-AdminLTE中的webpack-dev-server的HMR热更新不生效