利用组件架构与构建工具开发前端应用
1. 组件架构构建应用
在前端开发中,组织文件是一项挑战,尤其是前端代码包含 HTML、CSS 和 JavaScript 等不同语言和文件类型。过去,开发者常按文件类型分离文件,根目录下有 css、js、img 等目录。这种方式本意良好,想将不同关注点分离,因为 HTML 标记(网站内容)、CSS(网站外观)和 JavaScript(网站响应)不同,似乎应放在不同目录。
但问题是,这些部分并非真正独立。除了一些全局样式,CSS 是为特定标记构建的。若标记被移除,相关 CSS 可能未被删除,造成空间浪费。
随着开发工具改进,组件架构模式出现。组件架构将所有相关代码组合到单个目录,通过逐个添加组件构建网页或应用,直到完成可用应用。
组件架构虽有优势,但依赖构建工具和框架。下面以 React 代码为例,展示组件架构的工作方式。
1.1 构建基本组件 - 版权声明
版权声明组件包含当前年份、版权声明和样式。以下是示例代码:
// architecture/component/simplifying-js-component/src/components/Copyright/Copyright.js
import React from 'react';
import './Copyright.css';
export default function CopyrightStatement() {
const year = new Date().getFullYear();
return (
<div className="copyright">
Copyright {year}
</div>
);
}
这里的标记在返回语句中,CSS 类名为 className,这是 React 框架的 JSX 语法。代码位于
src/components
目录下,每个组件有自己的目录,如
Copyright
目录包含
Copyright.css
、
Copyright.js
和
Copyright.spec.js
。
CSS 文件如下:
// architecture/component/simplifying-js-component/src/components/Copyright/Copyright.css
.copyright {
font-size: 10px;
margin: 1em 1em 1em 0;
float: left;
}
版权声明组件所需的所有内容都在
Copyright
目录中,便于共享和删除。
1.2 构建稍复杂组件 - 带图标按钮
带图标按钮组件需要样式、标记、图像资产和点击动作。为使组件可复用,应尽量少硬编码选项,通过依赖注入传递点击动作。示例代码如下:
// architecture/component/simplifying-js-component/src/components/IdeaButton/IdeaButton.js
import React from 'react';
import './IdeaButton.css';
import idea from './idea.svg';
export default function IdeaButton({ handleClick, message }) {
return (
<button
className="idea-button"
onClick={handleClick}
>
<img
className="idea-button__icon"
src={idea}
alt="idea icon"
/>
{ message }
</button>
);
}
在 React 中,可通过函数参数访问注入的依赖,使用解构赋值提取。同时,导入图像到变量并设置
src
属性。
1.3 构建页面组件
页面组件包含想法按钮和页脚版权声明。示例代码如下:
// architecture/component/simplifying-js-component/src/App.js
import React from 'react';
import './App.css';
import IdeaButton from './components/IdeaButton/IdeaButton';
import Copyright from './components/Copyright/Copyright';
function logIdea() {
console.log('Someone had an idea!');
}
export default function App() {
return (
<div className="main">
<div className="app">
<IdeaButton
message="I have an idea!"
handleClick={logIdea}
/>
</div>
<footer>
<Copyright />
<IdeaButton
message="Footer idea!"
handleClick={logIdea}
/>
</footer>
</div>
);
}
App.js
是主组件,位于源代码根目录,导入并组合其他组件。
组件架构的优势在于将相关代码放在一起,便于开发和维护。但它需要构建工具将组件组合成浏览器可处理的代码。
以下是组件架构开发流程的 mermaid 流程图:
graph LR
A[开始] --> B[确定组件]
B --> C[创建组件目录]
C --> D[编写组件代码]
D --> E[组合组件]
E --> F[使用构建工具编译]
F --> G[部署应用]
G --> H[结束]
2. 使用构建工具组合组件
组件架构虽有优势,但无法在浏览器中直接运行,需要构建工具编译 JavaScript 代码和资产。
2.1 简化组件并准备编译
先取上一示例的简化版本,只保留 React JSX 形式的 HTML 和 JavaScript。以下是基本容器组件和版权组件代码:
// architecture/build/initial/src/App.js
import React from 'react';
import Copyright from './components/Copyright/Copyright';
export default function App() {
return (
<div className="main">
<footer>
<Copyright />
</footer>
</div>
);
}
// architecture/build/initial/src/components/Copyright/Copyright.js
import React from 'react';
export default function CopyrightStatement() {
const year = new Date().getFullYear();
return (
<div className="copyright">
Copyright {year}
</div>
);
}
这些文件无法在浏览器中运行,需要工具将 ES6 语法和 JSX 转换为兼容代码。
2.2 安装 Babel 进行代码转换
Babel 是处理现代 JavaScript 的重要工具,可将前沿 JavaScript 转换为浏览器友好代码。安装命令如下:
npm install --save-dev babel-cli babel-preset-env babel-preset-react
创建
.babelrc
文件配置 Babel:
// architecture/build/initial/.babelrc
{ "presets": ["env", "react"] }
在
package.json
文件中添加脚本进行编译:
// architecture/build/initial/package.json
{
"name": "initial",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "babel src/index.js -o build/bundle.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.24.1"
},
"dependencies": {
"react": "^16.1.1",
"react-dom": "^16.1.1"
}
}
更新
index.html
使用编译后的代码:
<!-- architecture/build/initial/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title>Sample</title>
</head>
<body>
<div id="root">
</div>
<script src="./build/bundle.js"></script>
</body>
</html>
但打开文件会报错,因为 Babel 不包含模块加载器。
2.3 安装 Webpack 组合代码
Webpack 可处理 JavaScript 组合、CSS 或 SASS 处理和图像转换。安装 Webpack 和 Babel 加载器:
npm install --save-dev babel-loader webpack
创建
webpack.config.js
文件配置 Webpack:
// architecture/build/webpack/webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
module: {
loaders: [
{
test: /\.js?/,
use: 'babel-loader',
},
],
},
output: {
filename: 'build/bundle.js',
path: path.resolve(__dirname),
},
};
更新
package.json
脚本调用 Webpack:
{
"scripts": {
"build": "webpack"
}
}
运行脚本后,代码可在浏览器中显示。
2.4 处理 CSS 和图像
处理 CSS 时,安装
css-loader
和
style-loader
:
npm install --save-dev css-loader style-loader
更新
webpack.config.js
配置 CSS 加载器:
// architecture/build/css/webpack.config.js
module: {
loaders: [
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
],
},
{
test: /\.js?/,
use: 'babel-loader',
},
],
}
处理图像时,使用
file-loader
移动和重命名文件:
// architecture/build/img/webpack.config.js
module: {
loaders: [
{
test: /\.svg?/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'build/',
},
},
],
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
],
},
{
test: /\.js?/,
use: 'babel-loader',
},
],
}
运行构建脚本,打开
index.html
即可看到组件。
构建工具处理流程如下表所示:
| 步骤 | 工具 | 操作 |
| ---- | ---- | ---- |
| 1 | Babel | 安装
babel-cli
、
babel-preset-env
和
babel-preset-react
,配置
.babelrc
文件 |
| 2 | Webpack | 安装
babel-loader
和
webpack
,创建
webpack.config.js
文件配置加载器 |
| 3 | CSS 处理 | 安装
css-loader
和
style-loader
,更新
webpack.config.js
配置 CSS 加载器 |
| 4 | 图像处理 | 使用
file-loader
,更新
webpack.config.js
配置图像加载器 |
总之,使用组件架构和构建工具可使前端开发更高效,但需逐步添加配置,耐心处理每个步骤。
3. 构建工具的进一步优化与拓展
3.1 构建工具配置的优化
随着项目的发展,构建工具的配置可能会变得复杂。为了提高构建效率和代码的可维护性,我们可以对配置进行优化。
例如,在
webpack.config.js
中,可以使用
cache
选项来缓存编译结果,避免重复编译:
// architecture/build/optimized/webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
cache: {
type: 'filesystem',
buildDependencies: {
config: [__filename]
}
},
module: {
loaders: [
{
test: /\.js?/,
use: 'babel-loader',
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
],
},
{
test: /\.svg?/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'build/',
},
},
],
},
],
},
output: {
filename: 'build/bundle.js',
path: path.resolve(__dirname),
},
};
还可以使用
splitChunks
选项来分割代码,将公共模块提取出来,减少重复代码:
// architecture/build/optimized/webpack.config.js
// ... 其他配置
optimization: {
splitChunks: {
chunks: 'all',
},
},
// ... 其他配置
以下是构建工具配置优化的步骤列表:
1. 开启缓存:在
webpack.config.js
中添加
cache
选项。
2. 代码分割:使用
splitChunks
选项将公共模块提取出来。
3. 按需加载:对于大型项目,可以使用动态导入实现按需加载。
3.2 处理更多类型的文件
除了 JavaScript、CSS 和 SVG 图像,项目中可能还会有其他类型的文件,如字体文件、JSON 文件等。我们可以通过配置 Webpack 来处理这些文件。
处理字体文件,安装
file-loader
并在
webpack.config.js
中添加配置:
// architecture/build/more-files/webpack.config.js
module: {
loaders: [
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'build/fonts/',
},
},
],
},
// ... 其他配置
],
}
处理 JSON 文件,Webpack 本身支持 JSON 文件的导入,无需额外配置。
以下是处理不同类型文件的表格:
| 文件类型 | 加载器 | 配置示例 |
| ---- | ---- | ---- |
| 字体文件(woff、woff2、eot、ttf、otf) |
file-loader
|
test: /\.(woff|woff2|eot|ttf|otf)$/, use: [{ loader: 'file-loader', options: { outputPath: 'build/fonts/' } }]
|
| JSON 文件 | 无需额外配置 | 直接导入使用 |
3.3 开发环境与生产环境的区分
在开发和生产环境中,我们对构建的需求可能不同。开发环境需要快速构建和热更新,而生产环境需要优化代码和压缩文件。
可以通过
webpack-merge
来合并不同环境的配置。首先,创建
webpack.common.js
、
webpack.dev.js
和
webpack.prod.js
文件。
webpack.common.js
包含公共配置:
// architecture/build/environments/webpack.common.js
const path = require('path');
module.exports = {
entry: './src/index.js',
module: {
loaders: [
{
test: /\.js?/,
use: 'babel-loader',
},
// ... 其他配置
],
},
output: {
filename: 'build/bundle.js',
path: path.resolve(__dirname),
},
};
webpack.dev.js
包含开发环境配置:
// architecture/build/environments/webpack.dev.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
});
webpack.prod.js
包含生产环境配置:
// architecture/build/environments/webpack.prod.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');
const TerserPlugin = require('terser-webpack-plugin');
module.exports = merge(common, {
mode: 'production',
optimization: {
minimizer: [
new TerserPlugin(),
],
},
});
以下是区分开发和生产环境的 mermaid 流程图:
graph LR
A[开始] --> B{环境类型}
B -->|开发环境| C[使用 webpack.dev.js 配置]
B -->|生产环境| D[使用 webpack.prod.js 配置]
C --> E[快速构建和热更新]
D --> F[优化代码和压缩文件]
E --> G[开发调试]
F --> H[部署上线]
G --> I[结束]
H --> I
4. 总结与展望
通过组件架构和构建工具,我们可以将前端代码组织得更加清晰,提高开发效率和代码的可维护性。组件架构将相关的 HTML、JavaScript 和 CSS 组合在一起,方便管理和复用。而构建工具则可以将这些组件编译成浏览器可处理的代码,并进行优化和压缩。
在实际项目中,我们需要根据项目的规模和需求,选择合适的组件架构和构建工具。同时,要不断学习和掌握新的技术和工具,以适应不断变化的前端开发环境。
未来,前端开发可能会朝着更加智能化、自动化的方向发展。构建工具可能会更加智能地分析代码,自动进行优化和配置。组件架构也可能会更加灵活和高效,支持更多的功能和场景。
总之,掌握组件架构和构建工具是前端开发者必备的技能,希望大家能够通过不断实践和学习,在前端开发的道路上取得更好的成绩。
超级会员免费看
172万+

被折叠的 条评论
为什么被折叠?



