小岳 發表於 2020-6-16 11:01:00

express+react

<h2 id="2283737595">1 开发环境准备(windows)#</h2>
<h4 id="2951686384">1.1 安装nodejs和npm#</h4>
<ul>
<li>
<p>1) 下载nodejs安装包:http://nodejs.org/en/download/</p>
<blockquote>nodejs安装时会同时安装npm</blockquote>
</li>
<li>2) 安装完成后检查是否安装成功</li>
</ul>
<blockquote>命令行输入以下命令,查看npm和node版本:<br><code>npm -v</code><br><code>node -v</code></blockquote>
<p>  若未安装成功可检查环境变量是否安装时自动设置成功</p>
<h4 id="1550301084">1.2 安装create-react-app(react官方提供的脚手架)#</h4>
<p>  命令行输入:<code>npm install -g create-react-app</code></p>
<blockquote>create-react-app:可以用来快速创建react项目<br>-g:全局安装create-react-app脚手架工具,这个步骤只需要执行一次</blockquote>
<h4 id="3095723053">1.3 安装express-generator(express官方提供脚手架)#</h4>
<p>  命令行输入:&nbsp;<code>npm install express-generator -g</code></p>
<blockquote>express-generator:可以用来快速创建express应用<br>-g:全局安装express-generator脚手架工具,这个步骤只需要执行一次</blockquote>
<h2 id="3062407836">2 创建react+express项目#</h2>
<blockquote>前端框架:react<br>服务端:基于node的express框架</blockquote>
<p>  两者结合快速创建web项目。由于服务端代码需要部署到服务器,为了方便操作,先创建react项目,然后在react项目目录下创建express项目,将react的打包目录设置为express项目下的public文件。</p>
<h6>(1)创建react项目(client)</h6>
<div class="cnblogs_code">
<pre>create-react-app myapp</pre>
</div>
<h6>(2)创建express项目(server)</h6>
<div class="cnblogs_code">
<pre>cd myapp
express-generator --view=ejs server </pre>
</div>
<blockquote>添加模版引擎:--view=ejs,此处选择ejs作为模版引擎。还可以选择pub、jade等其它模版引擎</blockquote>
<h4 id="629888090">2.2 react初始项目目录结构#</h4>
<p>  使用create-react-app创建的项目,已经把webpack、babel等配置都封装到依赖项目react-script中,因此在目录外层无法看到webpack等配置文件。</p>
<ul>
<li>
<p>1)自动生成的项目目录介绍</p>
<ul>
<li>A. node_modules:项目依赖包目录,使用npm install xxx相关命令安装的依赖都会自动下载到该目录,无需提交至git;</li>
<li>
<p>B. public:公共目录,该目录下的文件都不会被webpack进行加载、解析和打包;通过npm run build进行打包时该目录下的所有文件将会直接被复制到build目录下;</p>
<ul>
<li>a) favicon.ico:网站图标(可替换删除)</li>
<li>b) index.html:页面模板,webpack打包后将输出文件引入到该模板内;index.html中通过环境变量%PUBLIC_URL%指向public目录路径;</li>
<li>c) manifest.json:PWA将应用添加至桌面的功能的实现依赖于manifest.json。通过manifest.json文件可以对</li>
</ul>
</li>
<li>
<p>C. src:&nbsp;是源码目录,该目录下除了index.js App.test.js registerServiceWorker.js 文件具有一定意义其余文件都是演示使用可直接删除。</p>
<ul>
<li>a) index.js:&nbsp;是整个项目的入口文件,也是webpack打包的入口文件;</li>
<li>b) App.js:项目创建后,可通过修改此文件来修改页面内容</li>
<li>c) App.test.js:&nbsp;测试单元演示文件,暂时并不知道干嘛用;可以直接删除;</li>
<li>d) registerServiceWorker.js:&nbsp;service worker 是在后台运行的一个线程,可以用来处理离线缓存、消息推送、后台自动更新等任务;registerServiceWorker就是为react项目注册了一个service worker,用来做资源的缓存,这样你下次访问时,就可以更快的获取资源。而且因为资源被缓存,所以即使在离线的情况下也可以访问应用(此时使用的资源是之前缓存的资源)。注意,registerServiceWorker注册的service worker 只在生产环境中生效,并且该功能只有在https下才能有效果;</li>
</ul>
</li>
<li>D. .gitignore:&nbsp;该文件是github过滤文件配置,即指定无需提交至git而忽略的文件,帮助查看方式,git help ignore</li>
<li>E. README.md:&nbsp;该文件是描述文件</li>
<li>F. package.json:&nbsp;定义了项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证等元数据)。部分依赖模块被隐藏;</li>
<li>G. package.lock.json:&nbsp;每次通过npm添加依赖或者更新包版本时 npm都会把相关版本信息写入package.lock.json文件;</li>
</ul>
</li>
<li>2)package.json配置</li>
</ul>
<p><span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-97bc06f62bb47378.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></span></p>
<ul>
<li>3)可用脚本命令说明</li>
</ul>
<p>首先说明:通过npm run 执行下面命令实际上是运行 node_modules/react-srcipt/script下对应的脚本文件;</p>
<ul>
<li>A.npm run start :&nbsp;开始项目,通过http://localhost:3000 可访问项目;</li>
<li>B. npm run build :&nbsp;项目打包,在生产环境中编译代码,并放在build目录中;所有代码将被正确打包,并进行优化、压缩同时使用hash重命名文件;执行该命令前需要在package.json中新增条配置"homepage": "."(上面配置文件已给出), 同时build后的项目需要在服务器下才能访问;否则打开的将是空白页面;</li>
<li>C. npm run test :&nbsp;交互监视模式下启动测试运行程序;</li>
<li>D. npm run eject :&nbsp;将隐藏的配置导出;需要知道的是create-react-app脚手架本质上是使用react-scripts进行配置项目,所有配置文件信息都被隐藏起来(node_modules/react-scripts);当需要手动修改扩展webpack配置时有时就需要将隐藏的配置暴露出来;特别需要注意的是该操作是一个单向操作,一旦使用eject,那么就不能恢复了(再次将配置隐藏);</li>
</ul>
<h4 id="3961310157">2.3 react项目配置#</h4>
<p>  create-react-app默认生成的是单入口单出口生产环境,统一通过react-script进行管理,无法满足复杂的多入口项目的需要,因此需要对项目进行配置,使其满足实际项目需要。可通过npm run eject来暴露所有内建配置,以方便我们对项目的配置进行修改。</p>
<h6>2.3.1 npm run eject</h6>
<p>  进入myapp根目录,执行以下命令:<code>npm run eject</code>。暴露所有内建配置,项目下会新增或对部分配置文件进行修改。<br>  根目录下新增config(配置文件)和script(脚本文件)目录。</p>
<blockquote>注意:此操作不可逆,一旦执行无法回退;<br>修改配置的其它方法:也可考虑采用react-app-rewired插件来实现配置覆盖。</blockquote>
<h6>2.3.2 多入口配置</h6>
<blockquote>项目默认只有index.js(src目录下)这一个入口文件。</blockquote>
<p>以在src目录下新增入口文件admin.js为例。<span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-84752c39b9d18b73.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"><br>需修改config中的配置文件来:</span></p>
<ul>
<li>1)修改webpcak.config.dev.js文件</li>
<li>A. 修改entry(新增js文件入口配置)</li>

</ul>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//这里我已经写成对象格式了
//有多少个页面就添加多少个key:value
//这里我已经添加了一个admin
//数组中的paths.appSrc+'/admin.js'就是这个html页面的入口文件
    entry: {
      index:[
            require.resolve('./polyfills'),
            require.resolve('react-dev-utils/webpackHotDevClient'),
            paths.appIndexJs,
      ],
      admin:[
            require.resolve('./polyfills'),
            require.resolve('react-dev-utils/webpackHotDevClient'),
            paths.appSrc + '/admin.js',
      ]
    }</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<p><span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-cc9885708f9ae921.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></span></p>
<ul>
<li>B. 修改plugins中的HtmlWebpackPlugin(配置html模版文件)</li>
</ul>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//多少个页面就new 多少个 HtmlWebpackPlugin
//并且在每一个里面的chunks都需要和上面的entry中的key匹配
//例如上面entry中有index和admin这两个。
//这里的chunks也需要是index和admin
    new HtmlWebpackPlugin({
      inject: true,
      chunks:["index"],
      template: paths.appHtml,
    }),
    new HtmlWebpackPlugin({
      inject: true,
      chunks:["admin"],
      template:paths.appHtml,
      filename:'admin.html'
    }),</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<ul>
<li>C.修改output</li>
</ul>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//由于原配置入口文件只有一个,因此output中的filename是写死的,
//增加多入口之后,输出文件名被写死,对应生成了多个boundle.js,
//后面生成的会覆盖前面生成的文件,所以需要制定输出的文件名不能写死
output: {
    path:paths.appBuild,
    pathinfo: true,
    filename: 'static/js/.bundle.js',
    chunkFilename: 'static/js/.chunk.js',
    publicPath: publicPath,
    devtoolModuleFilenameTemplate: info =&gt;
    path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'),
},</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<ul>
<li>2) 修改config下webpack.config.prod.js文件</li>
<li>A 修改entry</li>
</ul>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//这里的paths.appIndexJs和paths.appSrc+'/admin.js'是入口文件
    entry:{
      index:[
            require.resolve('./polyfills'),
            paths.appIndexJs
      ],
      admin:[
            require.resolve('./polyfills'),
            paths.appSrc+'/admin.js'
      ]
    }</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<ul>
<li>B 修改plugins中的HtmlWebpackPlugin</li>
</ul>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//和开发环境下一样,多少个html就new多少个 HtmllWebpackPlugin,每个都需要指定chunks,并且指定filename,在minify中配置是否压缩js、css等,这是生产环境下的配置
    new HtmlWebpackPlugin({
      inject: true,
      chunks:["index"],
      template: paths.appHtml,
      minify: {
      removeComments: true,
      collapseWhitespace: true,
      removeRedundantAttributes: true,
      useShortDoctype: true,
      removeEmptyAttributes: true,
      removeStyleLinkTypeAttributes: true,
      keepClosingSlash: true,
      minifyJS: true,
      minifyCSS: true,
      minifyURLs: true,
      },
    }),
    new HtmlWebpackPlugin({
      inject: true,
      chunks:["admin"],
      template: paths.appHtml,
      filename:'admin.html',
      minify: {
      removeComments: true,
      collapseWhitespace: true,
      removeRedundantAttributes: true,
      useShortDoctype: true,
      removeEmptyAttributes: true,
      removeStyleLinkTypeAttributes: true,
      keepClosingSlash: true,
      minifyJS: true,
      minifyCSS: true,
      minifyURLs: true,
      },
    }),</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<ul>
<li>3)在开发环境中如果想通过地址访问不同页面,需要修改webpackDevServer.config.js</li>
<li>A 修改historyApiFallback</li>
</ul>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//这里的rewrites:[ {from: /^\/admin.html/, to: '/build/admin.html' }] 数组里面是一个个对象,
//对象中前面的值是在开发时候访问的路径,例如 npm run start之后会监听 localhost:3000 ,
//此时在后面加上 /admin.html就会访问admin.html中的内容,默认是访问index.html;
//数组中的第二个值是生产环境下的文件的路径。
//如果有很多页面,就在rewrites中添加更多对象
    historyApiFallback: {
      disableDotRule: true,
      rewrites: [
      { from: /^\/admin.html/, to: '/build/admin.html' },
      ]
    },</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<h6>2.3.3 前端跨域问题配置</h6>
<blockquote>生产环境:本文中的项目,由于打包后的代码会放在server目录下的public文件夹下,也就是打包后的代码和server在同域下,不存在跨域问题。<br>开发环境:开发时,前端react项目和后端express项目运行时端口端口不同,存在跨域问题。</blockquote>
<p>开发环境跨域问题解决办法:在package.json中加入:<code>"proxy":http://localhost:5000 //后端所在域</code>。<br>如果需要后端存在多个域:</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//package.json中加入
"proxy": {
   "/api1": {
         "target": "http://api1.xxxx.com",
         "changeOrigin":true
   },
   "/api2":{
         "target":"http://api2.xxxx.com",
         "changeOrigin":true
   }
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<h6>2.3.4 文件路径简化配置</h6>
<p>  当页面嵌套过深时,import Apis from '../../common/apis',可通过webpack配置来简化路径。</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//修改webpack.config.dev与webpack.config.prod两个文件,加入相同配置
//增加方法
function resolve(dir) {
    return path.join(__dirname, '..', dir)
}
//修改 alias配置
alias: {
   'react-native': 'react-native-web',
    //加入配置
   '@src': resolve('src')
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<p>添加上述配置后,引入文件方式:<code>import Apis from '@src/common/apis'</code></p>
<blockquote>缺点:此方法能简化引用方法,但无法通过快捷键进入该引用文件。</blockquote>
<h6>2.3.5 webpack打包体积详情分布</h6>
<ul>
<li>1)安装:npm install –save-dev webpack-bundle-analyzer</li>
<li>2)配置:</li>
</ul>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//修改webpack.prod.conf.js文件,增加如下内容
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
    new BundleAnalyzerPlugin()
]
}
//修改package.json文件,在scripts中增加如下命令
“analyz”: “NODE_ENV=production npm_config_report=true npm run build”</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<ul>
<li>3)运行<code>npm run build</code>或<code>npm run analyz</code>,浏览器会自动打开127.0.0.1:8888,如下页面,可查看打包后文件分布,以及打包文件大小。</li>
</ul>
<p><span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-766c267600dc6821.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></span></p>
<h6>2.3.6 webpack构建打包优化</h6>
<ul>
<li>1)使用UglifyJSPlugin压缩js文件</li>
</ul>
<p>安装方法:&nbsp;<code>npm install uglifyjs-webpack-plugin --save-dev</code>&nbsp;</p>
<pre class="hljs stylus"><code class="hljs css">在<span class="hljs-selector-tag">webpack<span class="hljs-selector-class"><span class="hljs-selector-class">.config<span class="hljs-selector-class"><span class="hljs-selector-class">.prod<span class="hljs-selector-class"><span class="hljs-selector-class">.js文件中添加</span></span></span></span></span></span></span></code></pre>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
    plugins: [
         new UglifyJSPlugin(),
   ]
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<ul>
<li>2)生产环境去掉map文件:缩短build时间</li>
</ul>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//修改webpack.config.prod.js文件:
//注释devtool:shouldUseSourceMap? 'source-map':false
devtool:false,//增加
3)添加cache-loader,减少打包时间
//修改webpack.config.dev.js文件:
module:{
    rules:[{
      use:[
            //添加在最前面
          'cache-loader',
      ]
    }]
}</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<blockquote>在其它加载程序加载之前添加以将结果缓存在磁盘上</blockquote>
<ul>
<li>4)提取公共包:提取多个入口引入的公共依赖包</li>
</ul>
<p>修改webpack.config.prod.js文件</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>//修改entry文件,
entry:
//这里的paths.appIndexJs和paths.appSrc+'/admin.js'依然是每个html的入口文件
{
       index:[
         require.resolve('./polyfills'),
         paths.appIndexJs,
      ],
      admin:[
            require.resolve('./polyfills'),
            paths.appSrc+'/admin.js'
      ],
      //增加vendor
      vendor:['react','react-dom']
},
//修改plugin
plugin:{
    //新增以下代码
    new webpack.optimize.CommonsChunkPlugin({
      name: ["vendor"],
      // filename:'static/js/vendor..js',
      // minChunks: 3//三方库在逻辑代码中被调用两次(数字可以自定义), 将公共的代码提取出来
    }),
/* 防止 vendor hash 变化 */
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
    name: 'manifest',
    chunks: ['vendor']
}),
}
//修改plugins中的HtmlWebpackPlugin,在chunks中添加需要引入的公共包,
//其中公共包需放在后面,使其在加入html页面时能在其它js文件前面
new HtmlWebpackPlugin({    inject: true,    chunks:["index","vendor"],    template: paths.appHtml,    minify: {      removeComments: true,      collapseWhitespace: true,      removeRedundantAttributes: true,      useShortDoctype: true,      removeEmptyAttributes: true,      removeStyleLinkTypeAttributes: true,      keepClosingSlash: true,      minifyJS: true,      minifyCSS: true,      minifyURLs: true,    },}),new HtmlWebpackPlugin({    inject: true,    chunks:["admin","vendor"],    template: paths.appHtml,    filename:'admin.html',    minify: {      removeComments: true,      collapseWhitespace: true,      removeRedundantAttributes: true,      useShortDoctype: true,      removeEmptyAttributes: true,      removeStyleLinkTypeAttributes: true,      keepClosingSlash: true,      minifyJS: true,      minifyCSS: true,      minifyURLs: true,    },}),</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<h6>2.3.7 build命令</h6>
<p>  命令行输入:<code>npm run build</code>,出现以下文件夹,其中admin.html和index.html分别是不同的入口。<br><span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-72a8c271a4084986.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></span></p>
<h6>2.3.8 修改build后资源文件根路径</h6>
<p>  可在path.js文件中修改打包后资源文件路径,例如修改path.js文件中getServedPath方法中的‘/’,改为‘/build’,则打包后资源文件的路径会加上build,修改前资源文件路径中是没有build的。<span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-f7a4c7e19b5bb324.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></span></p>
<p>  本文中react+express的项目,无需修改资源文件根路径,因为express会配置资源文件所在目录为。</p>
<h4 id="97363811">2.4 express项目配置(与react结合)#</h4>
<h6>2.4.1 nodemon热启动</h6>
<p>  express框架中启动项目后,文件更新后需要手动重启node服务,修改才会生效。使用nodemon可以实现热启动,文件修改后自动重启使修改生效。<br>  在server根目录(express项目根目录)下运行以下命令,安装nodemon:<br><code>npm --save-dev install nodemon</code></p>
<div class="cnblogs_code">
<pre>//修改server(express项目根目录)目录下的package.json文件,将node改为nodemon
//将"start":"node ./bin/www"改为:
"start":"nodemon ./bin/www"</pre>
</div>
<p>&nbsp;</p>
<h6>2.4.2 react打包目录相关修改</h6>
<p>  为了方便,将react打包目录修改为server目录下public目录,可以避免每次打包后都需要将build目录下的文件在复制到server目录下。</p>
<div class="cnblogs_code">
<pre>//修改path.js文件,module.exports中的appBuild变量
//将appBuild: resolveApp('build'),改为
appBuild: resolveApp('server/public'),</pre>
</div>
<p>&nbsp;</p>
<h6>2.4.3 在react的package.json中增加server的启动命令</h6>
<p>  在webstorm中,会自动出现根目录下package.json中的scripts下的npm命令,为了方便启动server,可在react 根目录下的package.json文件中增加server的启动项。</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>"scripts": {
    "start": "node scripts/start.js",
    "server-start": "cd server &amp;&amp; npm run start",//增加server启动命令
    "build": "node scripts/build.js",
    "test": "node scripts/test.js"
},</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<h4 id="309924883">2.5 react开发调试工具#</h4>
<h6>2.5.1 react-developer-tools</h6>
<p>  浏览器扩展工具中搜索此插件并安装,可以查看到react组件结构<span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-f8b53293c3796200.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></span></p>
<h6>2.5.2 chrome下的source map</h6>
<p>  chrome引入了source-map文件,可以查看打包前代码。唯一要做的就是配置webpack自动生成source-map文件,这也很简单,在webpack.config.js中增加一行配置即可(需要重新启动webpack-dev-server使配置生效),create-react-app已做此配置,因此不需要再修改。<br><span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-d2ef88b8a8fb8c29.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></span></p>
<h6>2.5.3 Eslint(javascript代码检查工具)</h6>
<p>  Create-react-app已安装Eslint,可对eslint进行自定义配置规则。</p>
<h4 id="603378477">2.6 项目目录结构优化#</h4>
<h6>2.6.1 react项目目录结构优化</h6>
<p>  开发目录主要是src目录,因此需要修改的目录主要是src目录。</p>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>|——src
|————|common //公共组件目录,如http.js、cookie.js等
|————|components //基础组件、业务组件、业务代码抽象出的一些基础类,例如每个页面可以在此目录下建立一个文件存放相关组件。
|————|layouts //布局相关组件及其样式文件,如header.js、footer.js、menu.js等
|————|styles //公共样式文件
|————|static //公共的静态资源文件,如公共的图片资源文件等
|————|views //页面入口文件,可与comonents中的页面组件对应</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<p>如果使用了router和redux可在src下增加目录:</p>
<ul>
<li>redux:redux应用数据状态管理文件,包括actions、reducers、stores三个子目录</li>
<li>routes:路由管理模块</li>
<li>containers:应用根容器,用于连接redux和router</li>
</ul>
<p><span class="img-wrap"><img src="https://upload-images.jianshu.io/upload_images/15387632-6b7462bc1e496d0b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"></span></p>
<h6>2.6.2 express项目目录结构优化</h6>
<div class="cnblogs_code">
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
<pre>|——server // express项目根目录
|————|bin
|——————|www//服务器相关配置文件
|————|controllers //控制器层,处理前端请求
|————|models //数据库操作相关文件
|————|node_modules //npm包安装目录
|————|public //react打包目录,存放所有的html,js/css/图片等资源文件
|————|routes // 路由文件目录
|——————|api.js //api请求路由文件
|——————|pages.js // 页面请求路由文件
|————|utils // 公共文件目录
|——————|config.js //各种常量或公共方法
|——————|db.js // 数据库访问方法封装
|——————|http.js //http请求方法封装
|————|views // express框架自带,由于打包后的文件全放在public目录下,因此这个文件可不用了
|————|app.js //入口文件
|————|package.json
|————|package-lock.json</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><img src="https://common.cnblogs.com/images/copycode.gif"></span></div>
</div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>转自思否,原链接https://segmentfault.com/a/1190000017472925,原作者_jingjing</p><br><br>
来源:https://www.cnblogs.com/wsw8384/p/13139847.html
頁: [1]
查看完整版本: express+react