如何结合Webpack 4和Babel 7创建一个出色的React应用

I previously wrote an article called “How to conquer Webpack 4 and build a sweet React app.” Soon after I wrote the article, babel swooped in with a major breaking change and many of the packages got deprecated. So I decided to write a new tutorial.

我之前写过一篇名为“ 如何征服Webpack 4并构建一个出色的React应用程序 ”的文章 在我写了这篇文章后不久,babel进行了重大的重大更改,许多软件包被弃用了。 所以我决定写一个新的教程。

I will focus on setting up webpack with react which will have .scss support along with code splitting

我将重点介绍如何使用ract设置webpack ,它具有.scss支持以及代码拆分功能

The purpose for writing this again is simple: I want everyone to feel comfortable. Because setting up webpack can be really daunting. Especially for new developers out there. Follow along, and what seemed difficult and maybe scary will seem like a piece of cake.

再次编写此代码的目的很简单:我希望每个人都感到舒服。 因为设置webpack确实很艰巨。 特别是对于那里的新开发人员。 跟着走,似乎困难甚至可怕的事情似乎只是小菜一碟。

Before we start, here is the source code. I know this has loads of things in it. I plan to use the same code base to talk about webpack, react, SCSS, hot module replacement, testing with jest and enzyme, linting code, and adding a code formatter like prettier in other articles to come, so I will continuously keep on updating this code base. I will not bloat this code base — I promise.

在开始之前,这里是源代码 。 我知道里面有很多东西。 我计划使用相同的代码库来谈论Webpack,React,SCSS,热模块替换,用玩笑和酶进行测试,整理代码,并在以后的其他文章中添加像prettier这样的代码格式化程序,因此我将不断更新此代码库。 我保证不会夸大此代码库。

Note: If you feel like making a PR for the repository, you are more than welcome :) So let’s get started.

注意:如果您想为存储库创建PR,欢迎您::因此,让我们开始吧。

For simplicity sake, this article is only going to focus on;

为了简单起见,本文仅着重讨论;

  • Setting up Webpack 4 with Babel 7 for React

    使用Babel 7为React设置Webpack 4
  • Support for .SCSS

    支持.SCSS
  • Code Splitting

    代码分割
  • Development environment with HMR (Hot Module Replacement)

    具有HMR(热模块替换)的开发环境
  • Production configuration

    生产配置
  • Dividing your Webpack configuration into chunks

    将您的Webpack配置分为多个块
  • Handling staging, demo, production, test and other environments in code

    在代码中处理登台,演示,生产,测试和其他环境
  • Generating a visualizer in production build to check which chunk of code took how much size and what are the dependencies of the chunks. Super useful.

    在生产版本中生成可视化工具,以检查哪个代码块占用了多少大小以及这些块的依赖关系是什么。 超级有用。

先决条件 (Prerequisite)

You need to have node installed in order to use npm (node package manager).

您需要安装节点才能使用npm(节点程序包管理器)。

First things first, create a folder called app then open up your terminal and go into that app folder and type:

首先,创建一个名为app的文件夹,然后打开您的终端并进入该app文件夹并键入:

console.warn('I am a Star Trek nerd');
console.log('So through out this tutorial, you will see a lot of Star Trek quotes');
console.log('Starting now');
console.log("Compassion: that’s the one thing no machine ever had. Maybe it’s the one thing that keeps men ahead of them. -Dr McCoy");

You can write anything above of course. I chose Star Trek.

您当然可以写任何东西。 我选择了《星际迷航》。

Next we need to install a couple of dependencies. You can just copy the dependencies & devDependencies from the package.json below into your own and do an npm install:

接下来,我们需要安装几个依赖项。 您可以将下面的package.json中的dependenciesdevDependencies复制到自己的文件中,然后执行npm install

{"name": "react-boiler-plate","version": "1.0.0","description": "A react boiler plate","main": "src/index.js","author": "Adeel Imran","license": "MIT","scripts": {"start": "a script will come here"},"dependencies": {"react": "^16.5.2","react-dom": "^16.5.2"},"devDependencies": {"@babel/core": "^7.0.0","@babel/plugin-proposal-class-properties": "^7.0.0","@babel/plugin-proposal-export-namespace-from": "^7.0.0","@babel/plugin-proposal-throw-expressions": "^7.0.0","@babel/plugin-syntax-dynamic-import": "^7.0.0","@babel/polyfill": "^7.0.0-beta.51","@babel/preset-env": "^7.0.0-beta.51","@babel/preset-react": "^7.0.0-beta.51","babel-loader": "^8.0.0-beta.0","copy-webpack-plugin": "^4.5.1","css-loader": "^0.28.11","html-webpack-plugin": "^3.2.0","mini-css-extract-plugin": "^0.4.3","node-sass": "^4.8.3","optimize-css-assets-webpack-plugin": "^4.0.0","sass-loader": "^7.0.3","style-loader": "^0.21.0","uglifyjs-webpack-plugin": "^1.2.5","webpack": "^4.12.0","webpack-cli": "^3.0.8","webpack-dev-server": "^3.1.4","webpack-merge": "^4.1.3","webpack-visualizer-plugin": "^0.1.11"}
}

Yes I know, I know! That’s a lot to create a hello world react app. But wait, this is all you will need. Even if you want to create a enterprise level app. (Maybe one or two more things depending on your requirements, but this is the backbone for it.)

是的,我知道,我知道! 创建一个hello world react应用程序需要大量资源。 但是,等等,这就是您所需要的。 即使您要创建企业级应用程序。 (根据您的要求,也许还有一两件事,但这是它的基础。)

So let’s talk about each and everyone of them before we dive deep into the code.

因此,在深入研究代码之前,让我们谈谈每个人。

webpack: We need Webpack to bundle our code.

webpack :我们需要Webpack来捆绑我们的代码。

webpack-cli: We will be using some CLI features of Webpack to make our lives easier while writing some scripts.

webpack-cli :我们将使用Webpack的某些CLI功能,以简化编写脚本的过程。

webpack-dev-server: I will create a server using the webpack-dev-server package. This is only meant to be used in the development environment, and not for production. This means while developing and working on my code, I don’t need a separate server like NodeJS to setup manually.

webpack-dev-server :我将使用webpack-dev-server包创建服务器。 这仅用于开发环境,而不用于生产。 这意味着在开发和处理代码时,不需要像NodeJS这样的单独服务器即可进行手动设置。

webpack-merge: To divide our configuration into chunks, more on this later

webpack-merge :将我们的配置分为多个块,稍后会详细介绍

webpack-visualizer-plugin: To see a visual representation of each of our bundle size — how much space they are taking and what are their dependencies.

webpack-visualizer-plugin :要查看每个捆绑包大小的可视化表示-它们占用了多少空间以及它们之间的依赖关系。

style-loader: This adds CSS to the DOM by injecting a /> tag in the header

style-loader :这通过在标头中插入 />标签将CSS添加到DOM中

sass-loader: For SCSS support

sass-loader :用于SCSS支持

node-sass: A dependency for sass-loader

node-sass :sass-loader的依赖项

css-loader: To convert our .scss files into .css

css-loader :将我们的.scss文件转换为.css

mini-css-extract-plugin: This plugin extracts CSS into separate files. It creates a CSS file per JS file which contains CSS.

mini-css-extract-plugin :此插件将CSS提取到单独的文件中。 它为每个包含CSS的JS文件创建一个CSS文件。

uglifyjs-webpack-plugin: To minify JavaScript code for production

uglifyjs-webpack-plugin :最小化用于生产JavaScript代码

optimize-css-assets-webpack-plugin To minify CSS code for production

优化css-assets-webpack-plugin最小化CSS代码以进行生产

html-webpack-plugin: This does more then generate an HTML file, it supports on demand .css and .js files automatically added to your HTML files on demand

html-webpack-plugin :这会做更多的工作,然后生成一个HTML文件,它支持按需将.css和.js文件自动按需添加到您HTML文件中

copy-webpack-plugin: Copies files/folders to your build folder.

copy-webpack-plugin :将文件/文件夹复制到构建文件夹。

babel-loader: This is the loader that helps webpack compile .js files

babel-loader :这是帮助webpack编译.js文件的加载器

@babel/core: Babel core compiler, this is a dependency that lets you use babel-loader

@ babel / core :Babel核心编译器,这是一个依赖关系,可让您使用babel-loader

@babel/preset-react Babel preset for React code

@ babel / preset-react Babel预设为React代码

@babel/preset-env: Babel preset that allows you to use the latest JavaScript

@ babel / preset-env :Babel预设,允许您使用最新JavaScript

@babel/pollyfill: Babel includes a polyfill that includes a custom regenerator runtime and core-js. This will emulate a full ES2015+ environment. This means support for async/await type of cool syntax sugar.

@巴贝尔/ pollyfill :巴别包括填充工具 ,其包括一个自定义的再生器的运行时和核心-JS 。 这将模拟完整的ES2015 +环境。 这意味着支持async/await类型的凉爽语法糖。

Up till now this is pretty much what I wrote in How to conquer Webpack 4 and build a sweet React app.

到目前为止,这几乎是我在“ 如何征服Webpack 4和构建一个出色的React应用程序”中写的内容

So what changed?

那么,什么改变了?

Well! Babel introduced a breaking change (for the greater good, believe me) which you can read more here: Removing Babel’s Stage Preset. What this meant was that before if you included babel-preset-stage-2 let’s say, it would include all proposals related to stage-2, which would bloat your code. But you just might need one specific feature of stage-2.

好! Babel引入了一项重大突破(为了更大的利益,请相信我),您可以在此处内容: 删除Babel的舞台预设 这意味着如果在您包含babel-preset-stage-2之前,它会包含与stage-2相关的所有建议,这会使您的代码膨胀。 但是您可能只需要Stage-2的一项特定功能。

So in order to combat this, babel deprecated all those preset plugins and shipped individual features. You now have to set those up manually. Cool right? So let’s talk a bit about those individual packages and what they do.

因此,为了解决这个问题,babel弃用了所有这些预设插件,并提供了各个功能。 现在,您必须手动设置它们。 酷吧? 因此,让我们谈谈那些单独的软件包及其作用。

@babel/plugin-proposal-class-properties: Coverts your class syntax into a function for browsers that don’t support class syntax

@ babel / plugin-proposal-class-properties :将class语法隐藏到不支持class语法的浏览器的function

@babel/plugin-proposal-export-namespace-from Supports syntax like import * as ns from '../path/to/module';

@ babel / plugin-proposal-export-namespace-from支持类似import * as ns from '../path/to/module';语法,如import * as ns from '../path/to/module';

@babel/plugin-proposal-throw-expressions New syntax to throw exceptions from within an expression context. I love this feature :D

@ babel / plugin-proposal-throw-expressions用于从表达式上下文内引发异常的新语法。 我喜欢这个功能:D

@babel/plugin-syntax-dynamic-import This is what helps with code splitting. Webpack ships with code splitting by default (Since webpack 1). But when you want to code split in webpack while you are using babel, then you need to use this plugin.

@ babel / plugin-syntax-dynamic-import这有助于代码拆分。 Webpack默认附带代码拆分功能(自webpack 1起)。 但是,当您想在使用babel时在webpack中进行代码拆分时则需要使用此插件。

Note: for this tutorial you won’t need@babel/plugin-proposal-export-namsespace-from & @babel/plugin-proposal-throw-expressions

注意:对于本教程,您不需要@babel/plugin-proposal-export-namsespace-from@babel/plugin-proposal-throw-expressions

Also here is a list of all babel plugins. I mean all of them. Check out the list here.

这也是所有babel插件的列表。 我的意思是所有人。 这里查看清单

And now that you know why we need what we need — nothing extra — you’ll feel more confident implementing the webpack configuration.

现在,您知道了我们为什么需要我们所需要的东西(仅此而已),您将更加自信地实施webpack配置。

Let’s start by adding a .babelrc file in the root of out app folder:

首先,在out app文件夹的根目录中添加一个.babelrc文件:

module.exports = {module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader'}},]}
}

Once you have it in place, run this command in your root app directory. (I’ll tell you what this command does a bit later with the code we wrote above, I promise.)

安装到位后,在根app目录中运行此命令。 (我保证,稍后我将告诉您该命令对上面编写的代码做了什么)。

Tutorial

Let’s update our webpack.base.config.js as well:

让我们也更新我们的webpack.base.config.js

var HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader'}}]},plugins: [new HtmlWebpackPlugin({ template: './src/index.html', filename: './index.html' })]
}

Let’s run that command again now:

现在让我们再次运行该命令:

rules: [      {        test: /\.js$/,        exclude: /node_modules/,        use: {          loader: 'babel-loader'        }      },    
]

Here by saying test: /\.js$./, we are telling webpack to apply this rule only for .js files. The other thing is exclude which also takes in a regex expression of what not not to include. This is where we tell it not to compile node_modules because this will compile all of it, and there are loads of dependencies installed. Check the node_modules yourself. The last part is use.

这里说test: /\.js$./,我们告诉webpack仅将此规则应用于.js文件。 另一件事是exclude ,它也接受不包括在内的正则表达式。 这是我们告诉它不要编译node_modules因为它将编译所有代码,并且安装了许多依赖项。 自己检查node_modules 。 最后一部分是use

Now webpack knows where to apply the rule using test and where not to apply the rule using exclude — but what is the rule exactly? That is where use comes into play: here we specify loader: 'babel-loader'. Now what babel-loader does is that it looks for .babelrc file that we wrote earlier. And all the presets & plugins we wrote there. It takes all of them and applies those to our .js files.

现在,webpack知道在何处使用test应用规则,在何处不使用exclude应用规则,但是确切的规则是什么? 这就是use发挥作用的地方:这里我们指定loader: 'babel-loader' 。 现在, babel-loader作用是查找我们先前编写的.babelrc文件。 以及我们在此处编写的所有预设和插件。 它需要所有这些并将它们应用于我们的.js文件。

Which brings us to the next question: how does Webpack 4 find those files? Well Webpack 4 ships with loads of default stuff already set up for you. Two of those are entry and output .

这就引出了下一个问题: Webpack 4如何找到这些文件? Webpack 4附带了许多已经为您设置的默认内容。 其中两个是entryoutput

entry point by default is the src directory that we wrote in our app folder.

默认情况下, entry点是我们在app文件夹中编写的src目录。

output point is where all the compiled bundled code is generated, which is going to be dist folder in out app folder. (You won’t see that now, because we haven’t compiled our code yet for production.)

output点是生成所有已编译捆绑代码的位置,该代码将是out app文件夹中的dist文件夹。 (您现在不会看到它,因为我们还没有为生产而编译我们的代码。)

Next we’ll talk about html-webpack-plugin The purpose of this plugin is simple as the name suggests. It creates HTML files to serve all of your bundled files. (All of it — .js, .css, .scss, .img etc)

接下来,我们将讨论html-webpack-plugin顾名思义,此插件的用途很简单。 它创建HTML文件以提供所有捆绑文件。 (所有这些-.js,.css,.scss,.img等)

Let’s talk about when we run the following:

让我们谈谈何时运行以下命令:

import React from 'react';
import ReactDOM from 'react-dom';const App = () => {return (

We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequentlyhave my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be ableto prove it.

- Captain Kirk

); };ReactDOM.render(, document.getElementById('app'));

Now if your terminal is still running the webpack-dev-server script, just check the browser out. If not, here is the script. I don’t want you to scroll all the way up again.

现在,如果您的终端仍在运行webpack-dev-server脚本,只需将浏览器检出即可。 如果没有,这是脚本。 我不希望您再次向上滚动。

var HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader'}},{test: /\.scss$/,use: ['style-loader','css-loader','sass-loader']},]},plugins: [new HtmlWebpackPlugin({template: './src/index.html',filename: './index.html'}),]
}

So the use I use here takes an array instead of an object like what I did for the .js files. This is because we need to apply a set of rules here:

因此,我在这里use用法是一个数组,而不是像我对.js文件所做的那样的对象。 这是因为我们需要在此处应用一组规则:

body {background-color: skyblue;color: black;
}.app {width: 450px;margin: 0 auto;padding-top: 50px;
}

And my src/index.js file looks like this:

我的src/index.js文件如下所示:

import React from 'react';
import ReactDOM from 'react-dom';import './myStyles.scss';;const App = () => {return (

We are a most promising species, Mr. Spock, as predators go. Did you know that? I frequentlyhave my doubts. I dont. Not any more. And maybe in a thousand years or so, we will be ableto prove it.

- Captain Kirk

); };ReactDOM.render(, document.getElementById('app'));

Restart your webpack-dev-server by running this command again:

通过再次运行以下命令来重新启动webpack-dev-server

"scripts": {"start": "webpack-dev-server --mode development --config config/webpack.base.config.js --open --hot --history-api-fallback --env.PLATFORM=local --env.VERSION=stag","prebuild": "webpack --mode production --config config/webpack.prod.config.js --env.PLATFORM=production --env.VERSION=stag --progress","build": "node server",
},

For now I’ll talk about the start command. I’ll talk about the prebuild and build scripts later in the production configuration section.

现在,我将讨论start命令。 我将在生产配置部分稍后讨论prebuild buildbuild脚本。

So what does this command do: npm run start

那么,该命令的作用是: npm run start

const webpack = require('webpack');
const merge = require("webpack-merge");const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = env => {const { PLATFORM, VERSION } = env;return merge([{module: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader'}},{test: /\.scss$/,use: ['style-loader','css-loader','sass-loader']}]},plugins: [new HtmlWebpackPlugin({template: './src/index.html',filename: './index.html'}),new webpack.DefinePlugin({ 'process.env.VERSION': JSON.stringify(env.VERSION),'process.env.PLATFORM': JSON.stringify(env.PLATFORM)}),],}])
};

Previously where we where exporting an object, now we are exporting a function which returns merge and takes in the configuration.

以前我们在导出object ,现在我们正在导出一个返回merge并接受配置的function

Let’s break this down as to what this is doing.The first thing we talk about is this:

让我们来解释一下这是做什么的。我们谈论的第一件事是:

new MiniCssExtractPlugin(),
new OptimizeCssAssetsPlugin(),

The first will extract this into a separate module called main.css and the other will minify/uglify the generated CSS.

第一个将其提取到名为main.css的单独模块中,另一个将最小化/丑化生成CSS。

Having done this, we are almost 90% done. If you have stayed this far, kudos to you.

完成此操作后,我们几乎完成了90%。 如果您住得这么远,就对您表示敬意。

Before we proceed further, here is what Captain Kirk has to say

在继续之前,这是柯克船长必须说的

You know the greatest danger facing us is ourselves, and irrational fear of the unknown. There is no such thing as the unknown. Only things temporarily hidden, temporarily not understood.

您知道我们面临的最大危险是我们自己,以及对未知事物的非理性恐惧。 没有未知的事物。 只有暂时隐藏的东西,暂时无法理解。

- James T. Kirk, The Corbomite Maneuver
-詹姆斯·柯克(James T. Kirk),Corbomite演习

Let’s add more functionality, to our code. Now there are two ways to add files in your code. One is by using another loader called file-loader which will help you add files of any type into your .js files like we did with .scss files.

让我们在代码中添加更多功能。 现在,有两种方法可以在代码中添加文件。 一种方法是使用另一种称为file-loader ,它将像您对.scss文件所做的那样,帮助您将任何类型的文件添加到.js文件中。

I want to talk about another approach here, because I think assets like fonts, images and others should be loaded in parallel rather than in your .js files. This helps provide a better experience for the user. So for that propose we will load our images statically.

我想在这里讨论另一种方法,因为我认为应该并行加载字体,图像和其他资源,而不是.js文件。 这有助于为用户提供更好的体验。 因此,对于该建议,我们将静态加载图像。

For this we will use a plugin called copy-webpack-plugin. The best thing about all this is you already have this installed. In your webpack.base.config.js add another plugin, like the below:

为此,我们将使用一个名为copy-webpack-plugin 。 关于这一切的最好的事情是您已经安装了这个。 在您的webpack.base.config.js添加另一个插件,如下所示:

The copy-webpack-plugin takes in an argument called from. This tells the plugin where to locate the static files and then copy them in the dist folder. Here I am telling it to look for a folder called src/static and copy all of its content in the dist/ folder.

copy-webpack-plugin接受一个名为from的参数。 这告诉插件在哪里可以找到静态文件,然后将其复制到dist文件夹中。 在这里,我告诉它寻找一个名为src/static的文件夹,并将其所有内容复制到dist/文件夹中。

Once you have added this and set it up, all you have to do is, in your app/src folder, create a new folder called static . In this folder, create another folder called images so your folder will have a directory like this: app/src/static/images

添加并设置完毕后,您要做的就是在app/src文件夹中创建一个名为static的新文件夹。 在此文件夹中,创建另一个名为images文件夹,以便您的文件夹具有以下目录: app/src/static/images

I am going to put an image here called header.jpg, but you can call it whatever you like. This is the image I am using: https://unsplash.com/photos/Idi6I490p7I (Photo by Felix Mittermeier on Unsplash).

我将在此处放置一个名为header.jpg的图像,但是您可以随意命名。 这是我正在使用的图像: https : //unsplash.com/photos/Idi6I490p7I ( Felix Mittermeier在Unsplash上拍摄 )。

Now in order for this to work, you need to run the npm run prebuild command (I’ll talk more about npm run prebuild & npm run build later when we set up our NodeJS server with ExpressJS) because we need our static files to be copied. The npm run start command won’t copy this to the dist/ folder because it doesn’t compile code to the dist/ folder.

现在,为了使其正常工作,您需要运行npm run prebuild命令(稍后我们将ExpressJS设置为npm run prebuild服务器时,我将详细介绍npm run prebuildnpm run build ),因为我们需要将static文件复制。 npm run start命令不会将其复制到dist/文件夹,因为它不会将代码编译到dist/文件夹。

Once you have run the npm run prebuild command this is what you will see:

运行npm run prebuild命令后,将看到以下内容:

So how can we access this file in our code?

那么如何在代码中访问该文件呢?

I am going to make some changes in my index.js file along with myStyles.scss .You can follow along as well — we’re just adding an /> along with some .scss

我将与myStyles.scss一起在index.js文件中进行一些更改。您也可以遵循—我们只是在 />和some .scss中添加

The only thing to note here is in the index.js file where I add an image:

唯一需要注意的是在index.js文件中添加图像的位置:

header

The main thing is the path we give in the src.

最主要的是我们在src给出的路径。

Once you have added this, let’s check how this looks in the browser. Go and run npm run start command.

添加完后,让我们检查一下它在浏览器中的外观。 去运行npm run start命令。

让我们回顾一下到目前为止我们已经完成的成就 (Let’s recap what we have accomplished so far)
  • Setting up Webpack 4 with Babel 7 for React

    使用Babel 7为React设置Webpack 4
  • Support for .SCSS

    支持.SCSS
  • Development environment with HMR [For both .js & .scss]

    使用HMR的开发环境[.js和.scss都适用]
  • Production configuration

    生产配置
  • Dividing your Webpack configuration into chunks

    将您的Webpack配置分为多个块
  • Generating a visualizer in production build to check which chunk of code is how big and what are the dependencies of the chunks. Super useful.

    在生产版本中生成可视化工具,以检查哪个代码块有多大以及这些块的依存关系是什么。 超级有用。
  • Support for static files

    支持静态文件
我们仍然需要完成的事情 (Things We Still Need To Accomplish)
  • Add support for async/await in our code

    在我们的代码中添加对async/await支持

  • Create a NodeJS server using ExpressJS for our production build

    使用ExpressJS为我们的生产版本创建NodeJS服务器
  • Code Splitting

    代码分割

Let’s start with async/await first. For this purpose I am going to make a smart /> component. Inside this component I am going to call an API that gets me information about Captain Kirk, because he is awesome. So in our index.js add the following code:

让我们先从async/await开始。 为此,我将创建一个智能的 />组件。 在该组件内部,我将调用一个API,该API向我获取有关Kirk船长的信息,因为他很棒。 因此,在我们的index.js添加以下代码:

All I am doing here is calling an API using try/catch async/await and getting information about Captain Kirk. Simple right? This should work. Let’s fire this up in the browser.

我在这里所做的只是使用try/catch async/await调用API并获取有关Kirk上尉的信息。 简单吧? 这应该工作。 让我们在浏览器中启动它。

Run the command:

运行命令:

const path = require('path');
const webpack = require('webpack');
const merge = require("webpack-merge");const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');const APP_DIR = path.resolve(__dirname, '../src'); // <===== new stuff added heremodule.exports = env => {const { PLATFORM, VERSION } = env;return merge([{entry: ['@babel/polyfill', APP_DIR], // <===== new stuff added heremodule: {rules: [{test: /\.js$/,exclude: /node_modules/,use: {loader: 'babel-loader'}},{test: /\.scss$/,use: [PLATFORM === 'production' ? MiniCssExtractPlugin.loader : 'style-loader','css-loader','sass-loader']}]},plugins: [new HtmlWebpackPlugin({template: './src/index.html',filename: './index.html'}),new webpack.DefinePlugin({ 'process.env.VERSION': JSON.stringify(env.VERSION),'process.env.PLATFORM': JSON.stringify(env.PLATFORM)}),new CopyWebpackPlugin([ { from: 'src/static' } ]),],}])
};

Check line no.8 and line no.14 in the snippet added above.

检查上面添加的代码段中的第line no.8line no.14

By default Webpack 4 takes in entry point of src/. But if we want to have multiple entry points, we can customize the entry point as well. In my entry point I am just telling it two things:

默认情况下,Webpack 4接受src/入口点。 但是,如果我们要有多个入口点,则也可以自定义entry点。 在我的切入点中,我只是告诉两件事:

const path = require('path');
const router = require('express').Router();router.get('*', (req, res) => {const route = path.join(__dirname, '..', '..', 'dist', 'index.html');res.sendFile(route);
});module.exports = router;

Here we check that whatever the user comes on, the path redirects the user to the dist/index.html where our React application lives.

在这里,我们检查是否有用户参与,该路径会将用户重定向到React应用程序所在的dist/index.html

And that’s it. We are done.

就是这样。 我们完了。

Now go in your terminal and type:

现在进入终端并输入:

import Foo from './Foo';
class App extends React.Component {state = {};render() {return (

I am App

)} }

Well no, for a dynamic import we have to do this:

好吧,对于动态导入,我们必须这样做:

Things to note here are in line 9 line 14, 15, 16 line 40 line 57:

事情需要注意这里是line 9 line 14, 15, 16 line 40 line 57

  • Line 9: We Set Foo as null

    Line 9 :我们将Foo设置为null

  • Line 14, 15, 16 : As soon as our component mounts, we import our /> component

    Line 14, 15, 16 :装入组件后,我们将导入 />组件

Let’s talk more about this:

让我们更多地谈论这个:

import(/* webpackChunkName: 'Foo' */ './Foo').then(Foo => {     this.setState({Foo: Foo.default });    
})

Let’s break this down even more.

让我们进一步分解一下。

import(/* webpackChunkName: ‘Foo’ */ ‘./Foo’) : This has 2 parts to it, we set a chunk name called Foo in /* webpackChunkName: ‘Foo’ */. You can call this whatever you want. What this does is when your application loads the ./Foo file, it will get loaded by the name of Foo as defined in /* webpackChunkName: ‘Foo’ */

import(/* webpackChunkName: 'Foo' */ './Foo') :这有2个部分,我们在/* webpackChunkName: 'Foo' */设置了一个名为Foo的块名称。 您可以随便叫这个。 这是当您的应用程序加载./Foo文件时,它将按照/* webpackChunkName: 'Foo' */定义的Foo名称进行加载/* webpackChunkName: 'Foo' */

This feature is called magic comments in webpack, because it’s lets you name the file when you load it in your code.

此功能在webpack中称为魔术注释,因为它使您可以在将代码加载到文件中时为文件命名。

The other part of import(/* webpackChunkName: ‘Foo’ */ ‘./Foo’) is the ‘./Foo’ at the very end of the statement. This is the path from where we include our file.

import(/* webpackChunkName: 'Foo' */ './Foo')的另一部分是语句末尾的'./Foo' 。 这是我们包含文件的路径。

This returns us a promise .then(Foo => {}). Since our export of <Foo /> was export default when we set our state of Foo we set it to this.setState({Foo: Foo.default }); in order to assign the Foo component to the state variable Foo.

这返回给我们一个承诺.then(Foo => {})。 由于我们的出口of <富/ > was expor吨默认当我们设置我们的sta的Foo的TE我们小号et it to this.setState({Foo: Foo.de故障}); 为了将Foo组件分配给状态变量Foo。

line 57 : This is where we display our /> component. Unless it is not loaded i.e, it is null, we show a loading message. And once we have the &lt;Foo /> component we show it.

line 57 :这是我们显示 />组件的地方。 除非未加载,即为null,否则我们将显示加载消息。 并且一旦有了e the & lt; Foo />组件,我们就会展示它。

And that, my friends, is code splitting.

我的朋友们,这就是代码拆分。

I really do hope this was helpful for you. If it was please do let me know so that I can write more stuff like this. You can always reach me out on Twitter and again if you followed along till the end, I am really proud of you guys. YOU GUYS ARE ROCKING IT!

我确实希望这对您有所帮助。 如果是的话,请告诉我,以便我可以写更多这样的东西。 您随时可以在Twitter上与我联系 如果你们一直坚持到底,我真的为你们感到骄傲。 你们正在摇滚!



This article was originally published in Freecodecamp publication previously on Medium. Read here

本文最初发布在Freecodecamp出版物上,之前在Medium上。 在这里阅读

翻译自: https://www.freecodecamp.org/news/how-to-combine-webpack-4-and-babel-7-to-create-a-fantastic-react-app-845797e036ff/


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章