创建项目
创建文件夹 webpack-test
?
使用编辑器打开文件夹,我们初始化管理包 npm init -y
?生成一个默认的 pageage.json
?文件
要想创建react项目,思考我们之前使用都需要引入
import React from ‘react‘
// main.js
import ReactDom from ‘react-dom‘
这里不过多介绍这两个包,有需要的在本专栏应该会有相应文章进行描述~
所以我们安装这两个包
yarn add react react-dom --dev
或者
npm i react react-dom -d
这时候我们在项目目录下新建main.js文件并且添加 index.html
?用于加载 main.js
用,此时的目录结构应该如下:
// main.js
import React from ‘react‘
import ReactDom from ‘react-dom‘
function App() {
return (
<div>App</div>
)
}
ReactDom.render(<App/>, document.getElementById(‘root‘))
// index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
这时候写完了发现之前使用脚手架创建项目后都是按照文档里面的进行启动 npm run start
?(备注: npm start 是npm run start简写形式) 或者 yarn start
?,如果查看过创建的项目中的 package.json
?的,其中的 script
?是有start属性的:
这里的react-scripts是 create-react-app
? 为大家准备好的快捷项目创建包,可通过 rpm riun eject
?解构出完整的 webpack
?配置。
此时我们的项目的 package.json
?中只有:
没有 start
?命令,所以我们执行肯定无法打包并且生产并且打开浏览器。现在我们一步一步来实现这些~~
webpack
介绍create-react-app创建项目的流程
可跳过此部分内容直接看后面的部分这部分是简单介绍了官方脚手架的webpack配置
启动项目的命令
上面的react脚手架创建的项目中的命令start. 通过 react-scripts
?创建相当于:
上图显示start 会执行bin目录下的react-scripts.js 给的命令是start,我们打开对应目录查看文件:
我们在打开对应 scripts
?目录,查看 start.js
?,此文件一共183行。我们看下主要相关部分~
上图这段引入了相关的包比如 webpack
?, webpack-dev-server
?, react-dev-utils/clearConsole
?等~
标红的地方引入了webpack的基本配置
webpack.config.js?这个文件里面的内容会一点一点通过本教程介绍到~
devServer的配置
上图可以看到创建的devServer实例具有两个参数,第一个参数是创建的Compiler。Compiler具有一些可选的信息~
createCompiler(args: Object): WebpackCompiler
Creates a webpack compiler instance for WebpackDevServer with built-in helpful messages.
The object accepts a number of properties:args
appName : The name that will be printed to the terminal.string
config : The webpack configuration options to be provided to the webpack constructor.Object
devSocket : Required if is . This object should include and which are functions accepting an array of errors or warnings emitted by the type checking. This is useful when running with to report errors that are emitted after the webpack build is complete.ObjectuseTypeScripttrueerrorswarningsfork-ts-checker-webpack-pluginasync: true
urls : To provide the argument, use described below.ObjecturlsprepareUrls()
useYarn : If , yarn instructions will be emitted in the terminal instead of npm.booleantrue
useTypeScript : If , TypeScript type checking will be enabled. Be sure to provide the argument above if this is set to .booleantruedevSockettrue
tscCompileOnError : If , errors in TypeScript type checking will not prevent start script from running app, and will not cause build script to exit unsuccessfully. Also downgrades all TypeScript type checking error messages to warning messages.booleantrue
webpack : A reference to the webpack constructor.function
// 为devServer添加一些有用信息的Compiler
第二个参数是webpack的配置信息就是上面的附件内容,包括入口,输出,loader,plugins等内容
下图这段配置了devServer。调用了devServer类的listen方法:
图中代码可见创建的devServer是个webSocket链接~~~
以上就是设置端口并且启动的简单剖析~
webpack配置
-
安装
webpack webpack-cli
-
打开package.json文件添加命令
"scripts": {
"build": "webpack"
},
- 根目录下创建
webpack.config.js
?这是webpack 的默认配置文件名称,此时目录结构如下图:
- 配置
webpack.config.js
const path = require(‘path‘)
module.exports = {
entry: "./main.js",
output: {
path: path.resolve(__dirname, ‘dist‘),
filename: ‘[name].js‘
}
}
通过module.exports导出模块。
打包需要入口和出口文件(暂不考虑多文件入口和出口问题。后面会简单介绍)
入口使用entry属性标志,单入口直接写成字符串,多入口可以写成数组
输出的属性常用的有输出路径和输出文件名称~filename: ‘[name].js‘
?中的 [name]
?是占位符,可以根据对应输入文件名进行输出~
通过上面的一番配置,现在来试一下效果npm run build
?然后发现 -_- :
报错了~~
WARNING in configuration
The ‘mode‘ option has not been set, webpack will fallback to ‘production‘ for this value. Set ‘mode‘ option to ‘development‘ or ‘production‘ to enable defaults for each environment.
You can also set it to ‘none‘ to disable any default behavior. Learn more: https://webpack.js.org/configuration/mode/
ERROR in ./main.js 7:6
Module parse failed: Unexpected token (7:6)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| function App() {
| return (
> <div>
| App
| </div>
error Command failed with exit code 2.
显示警告: 提示未设置 mode
?,默认退回 production
?模式。通过设置mode可以启动不同环境下的模式,设置为node可以禁用默认行为。
这里的默认行为指的以下:
选项 | 描述 |
---|---|
development | 会将 process.env.NODE_ENV 的值设为 development。启用 NamedChunksPlugin 和 NamedModulesPlugin |
production | 会将 process.env.NODE_ENV 的值设为 production。启用 FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 UglifyJsPlugin. |
当开启生产模式的时候回启动一些plugins的配置。这就是第一个警告的所表达的意思。
报错信息
Module parse failed: Unexpected token (7:6)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
See https://webpack.js.org/concepts#loaders
模块解析失败配置一个可以处理这个文件类型的loader,目前没有配置loader来处理此文件~~
现在整理下目前的进度~
安装了依赖 react react-dom webpack webpack-cli
?然后配置了 package.json
?的 script
?后执行命令发现报错~因为没有安装处理这个类型的loader,为啥没有 loader
?就无法解析我们的 jsx
?语法呢?
loader
loader 用于对模块的源代码进行转换。loader 可以使你在?import?或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中?import?CSS文件!
loader可以处理js文件js的语法,无法处理jsx的语法,所以我们需要添加一个可以处理jsx语法的处理器、
这里进行js文件进行转译的loader是 babel-loader
?。
这里的babel-loader可以将高级的js语法转译成适用于配置中的兼容代码
看下配置方法:
- 不添加
.babelrc
?文件
// 此处loader的配置方式是module属性下面添加rules,然后test是匹配规则,exclude是不需要匹配的文件夹、文件
// use可以是字符串或者数组或者对象形式
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: ‘babel-loader‘,
options: {
presets: ["@babel/preset-env", "@babel/preset-react"]
}
}
}
]
}
- 添加
.babelrc
?文件形式
const path = require("path");
module.exports = {
entry: "./main.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: "babel-loader"
}
]
}
};
// .babelrc
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
重要的一步: 上面的loader配置好我们来试下,第一步安装需要的依赖
**
yarn add @babel/core @babel/cli @babel/preset-env @babel/preset-react babel-loader
安装完后此时文件目录如下
此时执行 npm run build
?后发现多出上面的dist目录。发现里面只有一个文件 main.js
?我们在index.html里面加载这个js文件~
<!doctype html>
<html lang="en">
<head>
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="./dist/main.js"></script>
</body>
</html>
打开这个index.html发现浏览器出现了我们添加的文字 App
?
到这里写的react文件可以正常被使用了
那想添加一点样式呢?下面介绍如何将添加的样式作用于当前文件
我们知道webpack本身无法处理关于css、less文件,所以我们添加 loader
?进行处理对应的文件让他能够处理如下形式的导入:
import ‘./index.css‘
我们安装 css-loader
?进行处理导入的css文件到js文件中(后面会介绍如何打包出单独的css文件),在webpack配置文件中添加配置
// 安装命令
yarn add css-loader
// webpack.config.js
module: {
rules:[
{
test: /\.(js|jsx)$/,
exclude: /(node_moudles)/,
use: "babel-loader"
},
{
test: /\.css$/,
exclude: /(node_moudles)/,
use: "css-loader"
}
]
}
然后我们引入一个css文件
#app {
font-size: 40px;
color: red;
}
执行 yarn build
?后打开引入js的html发现我们的样式并没有生效~
这是因为打包后并没有作用于页面代码 中。我们还需要一个loader将我们打包的样式作用于页面中 style-loader
Adds CSS to the DOM by injecting a?
<style>
?tag
通过在dom中插入style标签使得我们的css样式生效
同样安装 style-loader
?,配置
{
test: /\.css$/,
exclude: /(node_moudles|bower_components)/,
use: ["style-loader","css-loader"]
}
style-loader
?在 css-loader
?的前面取决于出现多个loader的时候加载顺序是从后往前的,需要先加载css内容后,再进行style标签的引入,所以style在css的前面,也就是后执行. yarn build
? 进行测试~
发现样式起到效果了!!!
当我们使用sass或者less的时候我们则需要添加对应的loader进行处理,这里介绍 sass-loader
?和 less-loader
?的配置,安装 yarn add node-sass sass-loader less less-loader
?然后进行配置
{
test: /\.(sc|le|c)ss$/,
exclude: /(node_moudles|bower_components)/,
use: ["style-loader","css-loader", "sass-loader" , "less-loader"]
}
修改 index.css
?为 index.less
?和 index.scss
?分别进行测试
测试通过~~~