懂小姐 發表於 2020-8-8 18:31:00

使用create-react-app 构建react应用(react-scripts)

<p>前言:</p>
<blockquote>
<p>create-react-app 是一个全局的命令行工具用来创建一个新的项目</p>
react-scripts 是一个生成的项目所需要的开发依赖</blockquote>
<p>&nbsp;&nbsp;<br>&nbsp; &nbsp; &nbsp; 一般我们开始创建react web应用程序的时候,要自己通过 npm 或者 yarn 安装项目的全部依赖,再写webpack.config.js,一系列复杂的配置,搭建好开发环境后写src源代码。<br>现在 如果你正在搭建react运行环境,使用 create-react-app 去自动构建你的app程序。你的项目所在的文件夹下是没有配置文件。react-scripts 是唯一的 额外的 构建依赖在你的package.json中,你的运行环境将有每一个你需要用来构建一个现代React app应用程序。你需要的依赖,和在配置文件中编写的配置代码,react-scripts 都帮你写了,比如:react-scripts帮你自动下载需要的 webpack-dev-server 依赖,然后react-scripts自己写了一个nodejs服务端的脚本代码 start.js来 实例化 WebpackDevServer ,并且运行启动了一个使用 express 的Http服务器,现在你只需要专心写src源代码就可以了。省去了很多精力,最适合快速上手一个demo了。<br><br>react-scripts有以下支持,都帮你配置好了:<br>React, JSX, ES6, and Flow syntax support.<br>Language extras beyond ES6 like the object spread operator.<br>Import CSS and image files directly from JavaScript.<br>Autoprefixed CSS, so you don’t need -webkit or other prefixes.<br>A build script to bundle JS, CSS, and images for production, with sourcemaps.<br>A dev server that lints for common errors.<br><br></p>
<p>Getting Started</p>
<p>安装</p>
<div class="cnblogs_code">
<pre>npm install -g create-react-app</pre>
</div>
<p>&nbsp;</p>
<p><br>创建一个应用程序&nbsp;</p>
<div class="cnblogs_code">
<pre>create-react-app my-<span style="color: rgba(0, 0, 0, 1)">app
cd my</span>-app</pre>
</div>
<p><br>生成的目录结构</p>
<div class="cnblogs_code">
<pre>my-app/<span style="color: rgba(0, 0, 0, 1)">
README.md
node_modules</span>/<span style="color: rgba(0, 0, 0, 1)">
package.json
.gitignore
</span><span style="color: rgba(0, 0, 255, 1)">public</span>/<span style="color: rgba(0, 0, 0, 1)">
    favicon.ico
    index.html
src</span>/<span style="color: rgba(0, 0, 0, 1)">
    App.css
    App.js
    App.test.js
    index.css
    index.js
    logo.svg</span></pre>
</div>
<p>&nbsp;</p>
<p>没有配置文件(webpack.config.js)</p>
<p>&nbsp;</p>
<p>运行应用程序</p>
<div class="cnblogs_code">
<pre>npm run start </pre>
</div>
<p>or&nbsp;</p>
<div class="cnblogs_code">
<pre>yarn start</pre>
</div>
<p>在浏览器中打开</p>
<pre><code class="language-groovy"><span class="hljs-attr">http:<span class="hljs-comment">//localhost:3000 </span></span></code></pre>
<p>现在我们看 my-app文件夹下的public/index.html 和src/index.js的源码,我们可以在这里编写项目代码,但是注意 public/index.html 是启动http服务器的首页,src/index.js是编译的入口文件,只能叫index这个名字,改别的名字不行。<br><br>打开 http://localhost:3000/index.html 首页,f12查看 网页源码,你会看到&nbsp;</p>
<div class="cnblogs_code">
<pre>&lt;script type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text/javascript</span><span style="color: rgba(128, 0, 0, 1)">"</span> src=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/static/js/bundle.js</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/script&gt;</pre>
</div>
<p>/static/js/bundle.js<br>在你的项目my-app你是看不到这个文件路径的,你也没有写配置文件webpack.config.js,<br>http服务器配置,自动代开浏览器窗口,react,es6语法编译,babel-core,webpack,等等这些 你都没下载,配置。<br>这些活,react-scripts 都帮你做了。</p>
<p>
刚才的过程分析&nbsp;</p>
<p>回顾&nbsp;<br>npm run start<br>我们 一开始这么启动服务 运行项目<br>打开你的my-app\package.json</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">scripts</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">start</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">react-scripts start</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      ...
}</span></pre>
</div>
<p>所以执行的是 react-scripts start&nbsp;<br>打开你的my-app\node_modules\react-scripts这个文件夹下的bin文件夹下的react-scripts.js文件</p>
<div class="cnblogs_code">
<pre>#!/usr/bin/<span style="color: rgba(0, 0, 0, 1)">env node
</span><span style="color: rgba(0, 0, 255, 1)">var</span> spawn = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">cross-spawn</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> script = process.argv[<span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">];
</span><span style="color: rgba(0, 0, 255, 1)">var</span> args = process.argv.slice(<span style="color: rgba(128, 0, 128, 1)">3</span><span style="color: rgba(0, 0, 0, 1)">);

</span><span style="color: rgba(0, 0, 255, 1)">switch</span><span style="color: rgba(0, 0, 0, 1)"> (script) {
</span><span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">build</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">eject</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">start</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">case</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">test</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
</span><span style="color: rgba(0, 0, 255, 1)">var</span> result =<span style="color: rgba(0, 0, 0, 1)"> spawn.sync(
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">node</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    .concat(args),
.......</span></pre>
</div>
<p>上面代码中 &nbsp;script 的变量值是 start<br>所以执行 my-app\node_modules\react-scripts\scripts 文件夹下的 &nbsp;start.js 文件代码节选重点如下</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> webpack = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">webpack</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> WebpackDevServer = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">webpack-dev-server</span><span style="color: rgba(128, 0, 0, 1)">'</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 启动http服务器</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> paths = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">../config/paths</span><span style="color: rgba(128, 0, 0, 1)">'</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">要编译的文件路径与生成路径等</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> config = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">../config/webpack.config.dev</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
</span><span style="color: rgba(0, 0, 255, 1)">var</span> DEFAULT_PORT = parseInt(process.env.PORT, <span style="color: rgba(128, 0, 128, 1)">10</span>) || <span style="color: rgba(128, 0, 128, 1)">3000</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这就是为什么 端口号 不是8080 而是 3000 的原因,在这里可以改成8080,重新npm run start 生效 </span>
detect(DEFAULT_PORT).then(port =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">if</span> (port ===<span style="color: rgba(0, 0, 0, 1)"> DEFAULT_PORT) {
    run(port); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这里开始运行</span>
    <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
}
......

function run(port) {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 这里可以设置 http协议, 或者可以在 npm run start 之前 cmd命令窗口中执行 set HTTPS=true&amp;&amp;npm start 改成https 安全协议</span>
<span style="color: rgba(0, 0, 255, 1)">var</span> protocol = process.env.HTTPS === <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">true</span><span style="color: rgba(128, 0, 0, 1)">'</span> ? <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https</span><span style="color: rgba(128, 0, 0, 1)">"</span> : <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 0, 255, 1)">var</span> host = process.env.HOST || <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">localhost</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;   
setupCompiler(host, port, protocol);</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 编译源码 ,生成路径</span>
runDevServer(host, port, protocol);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">启动 http服务器</span>
}</pre>
</div>
<pre><code class="language-javascript"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-string"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-string"><span class="hljs-comment"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-string"><span class="hljs-comment"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-string"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-number"><span class="hljs-number"><span class="hljs-comment"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword"><span class="hljs-comment"><span class="hljs-keyword"><span class="hljs-comment"><span class="hljs-keyword"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-keyword"><span class="hljs-string"><span class="hljs-comment"><span class="hljs-comment">

<span class="hljs-comment">//配置http服务器</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">function runDevServer(host, port, protocol) {
</span><span style="color: rgba(0, 0, 255, 1)">var</span> devServer = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> WebpackDevServer(compiler, {
   compress: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,   
    clientLogLevel: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">none</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    contentBase: paths.appPublic,   </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据导入的paths 指定应用根目录(即index.html所在目录)</span>
    hot: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,

    publicPath: config.output.publicPath, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据导入的 config 变量,指定 虚拟目录,自动指向path编译目录(/assets/ =&gt; /build/js/)。html中引用js文件时,
                                             </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">必须引用此虚拟路径(但实际上引用的是内存中的文件,既不是/build/js/也不是/assets/)。</span>
<span style="color: rgba(0, 0, 0, 1)">
    quiet: </span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,


    watchOptions: {
      ignored: </span>/node_modules/<span style="color: rgba(0, 0, 0, 1)">
    },
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Enable HTTPS if the HTTPS environment variable is set to 'true'</span>
    https: protocol === <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">https</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    host: host
});
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * 省略其他代码
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
    openBrowser(protocol </span>+ <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">://</span><span style="color: rgba(128, 0, 0, 1)">'</span> + host + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">:</span><span style="color: rgba(128, 0, 0, 1)">'</span> + port + <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">'</span>);    <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 打开浏览器 向服务器发送请求</span>
<span style="color: rgba(0, 0, 0, 1)">});
}


function setupCompiler(host, port, protocol) {

compiler </span>= webpack(config, handleCompile);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">根据导入的 config 变量指向的 webpack.config.dev 配置文件运行</span>
   <span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * 省略其他代码
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
}</span></pre>
</div>
<pre><code class="language-javascript"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-string"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-string"><span class="hljs-comment"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-string"><span class="hljs-comment"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-string"><span class="hljs-keyword"><span class="hljs-built_in"><span class="hljs-number"><span class="hljs-number"><span class="hljs-comment"><span class="hljs-function"><span class="hljs-params"><span class="hljs-keyword"><span class="hljs-comment"><span class="hljs-keyword"><span class="hljs-comment"><span class="hljs-keyword"><span class="hljs-string"><span class="hljs-string"><span class="hljs-string"><span class="hljs-keyword"><span class="hljs-string"><span class="hljs-comment"><span class="hljs-comment"><span class="hljs-comment">&nbsp;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p>&nbsp;start.js 文件代码 中 导入了 &nbsp;my-app\node_modules\react-scripts\config文件夹下的 &nbsp;webpack.config.dev.js 与 paths.js<br>paths.js &nbsp;代码节选如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">var</span> appDirectory = fs.realpathSync(process.cwd());   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 获取npm run start 运行所在的路径</span>
<span style="color: rgba(0, 0, 0, 1)">function resolveApp(relativePath) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> path.resolve(appDirectory, relativePath);
}

module.exports </span>=<span style="color: rgba(0, 0, 0, 1)"> {
appPath: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">.</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
ownPath: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">node_modules/react-scripts</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
appBuild: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">build</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
appPublic: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">public</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
appHtml: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">public/index.html</span><span style="color: rgba(128, 0, 0, 1)">'</span>),   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这就是一开始我们的项目 要使用public/index.html作为 默认首页
                </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这里写什么文件名,项目中就要使用什么文件名包括 也要有public文件夹</span>
appIndexJs: resolveApp(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">src/index.js</span><span style="color: rgba(128, 0, 0, 1)">'</span>),   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">编译的入口文件的文件名项目中要包括src文件夹</span>
appPackageJson: resolveApp(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">package.json</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
appSrc: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">src</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
yarnLockFile: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">yarn.lock</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
testsSetup: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">src/setupTests.js</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
appNodeModules: resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">node_modules</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> this is empty with npm3 but node resolution searches higher anyway:</span>
ownNodeModules: resolveOwn(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">node_modules</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">),
nodePaths: nodePaths,
publicUrl: getPublicUrl(resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">package.json</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)),
servedPath: getServedPath(resolveApp(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">package.json</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">))
};
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * 省略其他代码
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
webpack.config.dev.js代码节选如下:

</span><span style="color: rgba(0, 0, 255, 1)">var</span> paths = require(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./paths</span><span style="color: rgba(128, 0, 0, 1)">'</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">也导入了 同文件夹下的 paths.js</span>
module.exports = {entry: [    require.resolve(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react-dev-utils/webpackHotDevClient</span><span style="color: rgba(128, 0, 0, 1)">'</span>),    require.resolve(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./polyfills</span><span style="color: rgba(128, 0, 0, 1)">'</span>),    paths.appIndexJs   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 编译的入口文件],output: {    path: paths.appBuild,    pathinfo: true,       filename: 'static/js/bundle.js', </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 只是编译后生成的目标文件 ,这就是一开始我们 打开浏览器按f12看到的index.html导入的         </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">&lt;script type="text/javascript" src="/static/js/bundle.js"&gt;&lt;/script&gt;    publicPath: publicPath},</span>
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
   * 省略其他代码
   </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">

}</span></pre>
</div>
<p><br>&nbsp;</p>
<p>已经搭建好运行环境了,接下来 如何开发app<br><br>导入组件<br><br>由于babel依赖,这个项目支持es6模块<br>当你仍然使用require() and module.exports ,我们鼓励你去使用import and export 替代.<br><br>例如:&nbsp;</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Button.js

import React, { Component } </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Button extends Component {
render() {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> ...</span>
<span style="color: rgba(0, 0, 0, 1)">}
}
export </span><span style="color: rgba(0, 0, 255, 1)">default</span> Button; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 不要忘记去使用 export default!</span>
<span style="color: rgba(0, 0, 0, 1)">
DangerButton.js

import React, { Component } </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
import Button </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./Button</span><span style="color: rgba(128, 0, 0, 1)">'</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">从另一个文件导入一个组件</span>


<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> DangerButton extends Component {
render() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> &lt;Button color=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">red</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;<span style="color: rgba(0, 0, 0, 1)">;
}
}
export </span><span style="color: rgba(0, 0, 255, 1)">default</span> DangerButton;</pre>
</div>
<p>&nbsp;</p>
<p>增加样式</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">Button.css

.Button {
padding: 20px;
}
Button.js

import React, { Component } </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
import </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./Button.css</span><span style="color: rgba(128, 0, 0, 1)">'</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 告诉webpack Button.js 使用这些样式</span>


<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Button extends Component {
render() {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> You can use them as regular CSS styles</span>
    <span style="color: rgba(0, 0, 255, 1)">return</span> &lt;div className=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Button</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;<span style="color: rgba(0, 0, 0, 1)">;
}
}

Autoprefixer</span></pre>
</div>
<p>react-scripts 通过Autoprefixer 帮你的css文件自动添加浏览器兼容前缀<br>例如:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">.App {
display: flex;
flex</span>-<span style="color: rgba(0, 0, 0, 1)">direction: row;
align</span>-<span style="color: rgba(0, 0, 0, 1)">items: center;
}
变成

.App {
display: </span>-webkit-<span style="color: rgba(0, 0, 0, 1)">box;
display: </span>-ms-<span style="color: rgba(0, 0, 0, 1)">flexbox;
display: flex;
</span>-webkit-box-<span style="color: rgba(0, 0, 0, 1)">orient: horizontal;
</span>-webkit-box-<span style="color: rgba(0, 0, 0, 1)">direction: normal;
      </span>-ms-flex-<span style="color: rgba(0, 0, 0, 1)">direction: row;
          flex</span>-<span style="color: rgba(0, 0, 0, 1)">direction: row;
</span>-webkit-box-<span style="color: rgba(0, 0, 0, 1)">align: center;
      </span>-ms-flex-<span style="color: rgba(0, 0, 0, 1)">align: center;
          align</span>-<span style="color: rgba(0, 0, 0, 1)">items: center;
}</span></pre>
</div>
<p>&nbsp;</p>
<p>增加CSS预处理器</p>
<p>首先在 my-app/ &nbsp;目录下 &nbsp;安装node-sass用来将scss编译成css</p>
<div class="cnblogs_code">
<pre>npm install node-sass --save-dev</pre>
</div>
<p>打开my-app/package.json,增加以下代码到scripts中</p>
<div class="cnblogs_code">
<pre>   <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">scripts</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
</span>+    <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">build-css</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">node-sass src/ -o src/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
</span>+    <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">watch-css</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">npm run build-css &amp;&amp; node-sass src/ -o src/ --watch</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
   </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">start</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">react-scripts start</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
   </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">build</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">react-scripts build</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
   ......
    }</span></pre>
</div>
<p><br>现在你可以重新命名my-app/<code>src/App.css</code>&nbsp;to&nbsp;my-app/<code>src/App.scss</code>&nbsp;and 运行 &nbsp;&nbsp;<code>npm run watch-css<br></code>或者你可以改成</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">scripts</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">build-css</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">node-sass src/ -o src/</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">start</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">npm run build-css &amp;&amp; react-scripts start</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">先执行 build-css 再执行 react-scripts start</span>
    <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">build</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">react-scripts build</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">test</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">react-scripts test --env=jsdom</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">eject</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">react-scripts eject</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
}</span></pre>
</div>
<p>直接 npm run start<br><br><br>增加图片</p>
<div class="cnblogs_code">
<pre>import React <span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
import logo </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./logo.png</span><span style="color: rgba(128, 0, 0, 1)">'</span>; <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 告诉webpack 这个js文件使用这张图片</span>
<span style="color: rgba(0, 0, 0, 1)">
console.log(logo); </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> /logo.84287d09.png会改变图片的名字</span>
<span style="color: rgba(0, 0, 0, 1)">
function Header() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">导入结果是这个图片的url地址</span>
<span style="color: rgba(0, 0, 255, 1)">return</span> &lt;img src={logo} alt=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Logo</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;<span style="color: rgba(0, 0, 0, 1)">;
}

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> Header;</pre>
</div>
<p>当项目构建的时候,Webpack将正确的移动图片到构建的文件夹下,提供我们正确的路径</p>
<p>&nbsp;</p>
<p>在css工作中的方式也一样</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">.Logo {
background</span>-image: url(./<span style="color: rgba(0, 0, 0, 1)">logo.png);
}</span></pre>
</div>
<p>webpack发现所有的相对模块, 以 ./ &nbsp;开始<br><br></p>
<p>增加 bootstrap<br>在react+es6 moudle+bootstrap<br>你不是一定要React Bootstrap和React 一起使用,但是他是流行的库去整合 bootstrap 和react应用程序,如果你需要他,你可以通过Create React App整合他,通过以下几个步骤</p>
<p>首先安装React Bootstrap and Bootstrap从npm,React Bootstrap 不包括Bootstrap CSS ,所以你需要去安装<br>在&nbsp;my-app/ &nbsp;目录下&nbsp;&nbsp;安装</p>
<pre><code class="language-sql">npm <span class="hljs-keyword">install react-bootstrap <span class="hljs-comment">--save
npm <span class="hljs-keyword">install bootstrap@<span class="hljs-number">3 <span class="hljs-comment">--save</span></span></span></span></span></code></pre>
<p>&nbsp;</p>
<p>修改&nbsp;my-app/src/index.js<br>在你的src/index.js 文件内容的顶部,导入 Bootstrap CSS 和可选的 Bootstrap theme CSS</p>
<div class="cnblogs_code">
<pre>import React <span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
import ReactDOM </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react-dom</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
import </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">bootstrap/dist/css/bootstrap.css</span><span style="color: rgba(128, 0, 0, 1)">'</span>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 必须的</span>
import <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">bootstrap/dist/css/bootstrap-theme.css</span><span style="color: rgba(128, 0, 0, 1)">'</span>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">可选的</span>
import App <span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./App</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
import </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">./index.css</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;

ReactDOM.render(
</span>&lt;App /&gt;<span style="color: rgba(0, 0, 0, 1)">,
document.getElementById(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">root</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
);</span></pre>
</div>
<p>修改 my-app/src/App.js</p>
<div class="cnblogs_code">
<pre>import React, { Component } <span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
import { Grid, Navbar, Jumbotron, Button } </span><span style="color: rgba(0, 0, 255, 1)">from</span> <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">react-bootstrap</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> App extends Component {
render() {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
      </span>&lt;div&gt;
      &lt;Navbar inverse fixedTop&gt;
          &lt;Grid&gt;
            &lt;Navbar.Header&gt;
            &lt;Navbar.Brand&gt;
                &lt;a href=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;React App&lt;/a&gt;
            &lt;/Navbar.Brand&gt;
            &lt;Navbar.Toggle /&gt;
            &lt;/Navbar.Header&gt;
          &lt;/Grid&gt;
      &lt;/Navbar&gt;
      &lt;Jumbotron&gt;
          &lt;Grid&gt;
            &lt;h1&gt;Welcome to React&lt;/h1&gt;
            &lt;p&gt;
            &lt;<span style="color: rgba(0, 0, 0, 1)">Button
                bsStyle</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">success</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
                bsSize</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">large</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
                href</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">http://react-bootstrap.github.io/components.html</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
                target</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_blank</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;<span style="color: rgba(0, 0, 0, 1)">
                View React Bootstrap Docs
            </span>&lt;/Button&gt;
            &lt;/p&gt;
          &lt;/Grid&gt;
      &lt;/Jumbotron&gt;
      &lt;/div&gt;<span style="color: rgba(0, 0, 0, 1)">
    );
}
}

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> App;</pre>
</div>
<p>最后 运行</p>
<div class="cnblogs_code">
<pre>npm run start</pre>
</div>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/it-Ren/p/13458930.html
頁: [1]
查看完整版本: 使用create-react-app 构建react应用(react-scripts)