Tạo React Boilerplate – Từ a tới z
Một ngày nào đó bạn ko muốn dùng create-react-app để khởi tạo project nữa, thì đây chính là bài hướng dẫn bạn cần đọc: setup một project từ a tới z mà không dùng create-react-app
Tạo thư mục mới nào
mkdir react-bolt
Vào bên trong thư mục react-bolt
vừa tạo, chạy lệnh init
npm init -y
Lệnh này sẽ khởi tạo một project npm, trong đó có file package.json
, nơi chúng ta chứa toàn bộ những dependencies
Chúng ta tạo thêm một số thư mục cần thiết khác
react-bolt
|--config
|--src
|--tests
Tiến hành cài đặt webpack
và một số plugin
npm i --save-dev webpack webpack-cli webpack-dev-server webpack-merge html-webpack-plugin clean-webpack-plugin img-loader url-loader file-loader
Bên trong thư mục config
, chúng ta tạo thêm thư mục tên webpack
, chúng ta tạo lần lượt 5 file bên dưới trong thư mục webpack
paths.js
import path from 'path';
module.exports = {
root: path.resolve(__dirname, '../', '../'),
outputPath: path.resolve(__dirname, '../', '../', 'build'),
entryPath: path.resolve(__dirname, '../', '../', 'src/index.js'),
templatePath: path.resolve(__dirname, '../', '../', 'src/index.html'),
imagesFolder: 'images',
fontsFolder: 'fonts',
cssFolder: 'css',
jsFolder: 'js'
};
rules.js
module.exports = [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader'
}
},
{
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
exclude: /node_modules/,
loader: 'file-loader'
},
{
test: /\.(woff|woff2)$/,
exclude: /node_modules/,
loader: 'url-loader?prefix=font/&limit=5000'
},
{
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
exclude: /node_modules/,
loader: 'url-loader?limit=10000&mimetype=application/octet-stream'
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: ['url-loader?limit=10000', 'img-loader']
}
];
webpack.common.babel.js
import webpack from 'webpack';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import paths from './paths';
import rules from './rules';
module.exports = {
entry: paths.entryPath,
module: {
rules
},
resolve: {
modules: ['src', 'node_modules'],
extensions: ['*', '.js', '.scss', '.css']
},
plugins: [
new webpack.ProgressPlugin(),
new HtmlWebpackPlugin({
template: paths.templatePath,
minify: {
collapseInlineTagWhitespace: true,
collapseWhitespace: true,
preserveLineBreaks: true,
minifyURLs: true,
removeComments: true,
removeAttributeQuotes: true
}
})
]
};
webpack.dev.babel.js
import webpack from 'webpack';
import paths from './paths';
import rules from './rules';
module.exports = {
mode: 'development',
output: {
filename: '[name].js',
path: paths.outputPath,
chunkFilename: '[name].js'
},
module: {
rules
},
performance: {
hints: 'warning',
maxAssetSize: 450000,
maxEntrypointSize: 8500000,
assetFilter: assetFilename => {
return (
assetFilename.endsWith('.css') || assetFilename.endsWith('.js')
);
}
},
optimization: {
splitChunks: {
chunks: 'all'
}
},
devServer: {
contentBase: paths.outputPath,
compress: true,
hot: true,
historyApiFallback: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
webpack.prod.babel.js
import CleanWebpackPlugin from 'clean-webpack-plugin';
import paths from './paths';
import rules from './rules';
module.exports = {
mode: 'production',
output: {
filename: `${paths.jsFolder}/[name].[hash].js`,
path: paths.outputPath,
chunkFilename: '[name].[chunkhash].js'
},
module: {
rules
},
plugins: [
new CleanWebpackPlugin([paths.outputPath.split('/').pop()], {
root: paths.root
})
],
devtool: 'source-map'
};
Bên trong webpack.common.babel.js
chúng ta sẽ setup entry và output và các plugin. Các thiết đặt để chạy môi trường dev sẽ nằm trong webpack.dev.babel.js
và môi trường production sẽ nằm trong webpack.prod.babel.js
Tham khảo việc làm React hấp dẫn cho SV
Sau cùng, bên trong thư mục gốc, tạo thêm file webpack.config.js
nó sẽ merge 3 file config common, dev, prod lại
require('@babel/register');
const webpackMerge = require('webpack-merge');
const common = require('./config/webpack/webpack.common.babel');
const envs = {
development: 'dev',
production: 'prod'
};
/* eslint-disable global-require,import/no-dynamic-require */
const env = envs[process.env.NODE_ENV || 'development'];
const envConfig = require(`./config/webpack/webpack.${env}.babel`);
module.exports = webpackMerge(common, envConfig);
Babel
Cái các plugin cần thiết cho babel
npm install --save-dev @babel/core @babe/cli @babel/node @babel/plugin-proposal-class-properties @babel/plugin-proposal-object-rest-spread @babel/plugin-syntax-dynamic-import @babel/plugin-syntax-import-meta @babel/plugin-transform-async-to-generator @babel/plugin-transform-runtime @babel/preset-env @babel/preset-react @babel/register @babel/runtime babel-eslint babel-jest babel-loader [email protected]
Tạo file .babelrc
bên trong thư mục gốc, thiết đặt babel khi chạy
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
],
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-transform-runtime",
"@babel/plugin-transform-async-to-generator",
"@babel/plugin-proposal-class-properties"
]
}
Eslint
Cài đặt package
npm install --save-dev eslint eslint-config-airbnb eslint-config-prettier eslint-loader eslint-plugin-babel eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react Bên trong thư mục gốc, tạo file .eslintrc để cấu hình cho eslint
{
"parser": "babel-eslint",
"extends": ["airbnb", "prettier", "prettier/react"],
"plugins": ["prettier"],
"parserOptions": {
"ecmaVersion": 6,
"ecmaFeatures": {
"jsx": true
}
},
"env": {
"browser": true,
"node": true,
"mocha": true,
"es6": true,
"jest": true
},
"rules": {
"indent": ["error", 4],
"space-before-function-paren": "off",
"react/prefer-stateless-function": "warn",
"react/jsx-one-expression-per-line": "off",
"import/no-extraneous-dependencies": [
"error",
{ "devDependencies": true }
],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"linebreak-style": "off",
"global-require": "off",
"semi": "warn",
"arrow-body-style": "off",
"no-multiple-empty-lines": ["warn", { "max": 1 }],
"no-unused-expressions": [
"error",
{
"allowTaggedTemplates": true
}
],
"no-underscore-dangle": [
2,
{ "allow": ["__REDUX_DEVTOOLS_EXTENSION__"] }
]
}
}
Prettier
Cài đặt package
npm install --save-dev prettier
Tạo file .prettierrc
với nội dung
{
"printWidth": 80,
"tabWidth": 4,
"semi": true,
"singleQuote": true,
"bracketSpacing": true
}
React
Cuối cùng chúng ta chỉ còn cài React nữa là xong
npm install --save react react-dom cross-env
Bên trong thư mục src
, tạo file index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>React Bolt</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
File index.js
trong thư mục src
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
Mấy cái router, redux thì bạn cứ xem tài liệu của tụi nó nhé.
Jest
Bạn có thể dùng cái khác để test, nhưng Jest thì phổ biến nhất rồi
npm install --save-dev jest jest-dom react-testing-library
Bổ sung lệnh để chạy test trong package.json
"jest": {
"setupFiles": [
"<rootDir>/config/tests/jest.config"
],
"transform": {
"^.+\\.js$": "babel-jest"
}
},
"scripts": {
"start": "cross-env NODE_ENV=development webpack-dev-server --open",
"build": "cross-env NODE_ENV=production webpack",
"lint": "eslint ./src/**/**.js",
"lint:fix": "eslint ./src/**/**.js --fix",
"test": "jest",
"test:watch": "npm run test --watch",
"test:cover": "npm run test --coverage"
}
config/tests/jest.config.js
module.exports = {
automock: false,
browser: false,
bail: false,
collectCoverageFrom: [
'src/**/*.{js,jsx}',
'!**/node_modules/**',
'!**/vendor/**'
],
coverageDirectory: '<rootDir>/coverage',
globals: {
__DEV__: true
},
moduleFileExtensions: ['js', 'json', 'jsx', 'node'],
transform: {
'^.+\\.js?$': 'babel-jest'
},
verbose: true,
setupTestFrameworkScriptFile: './rtl.setup.js'
};
config/tests/rtl.setup.js
// See https://github.com/kentcdodds/react-testing-library#global-config
import 'jest-dom/extend-expect';
import 'react-testing-library/cleanup-after-each';
TopDev via Vuilaptrinh
- B BenQ RD Series – Dòng Màn Hình Lập Trình 4k+ Đầu Tiên Trên Thế Giới
- i iOS 18 có gì mới? Có nên cập nhật iOS 18 cho iPhone của bạn?
- G Gamma AI là gì? Cách tạo slide chuyên nghiệp chỉ trong vài phút
- P Power BI là gì? Vì sao doanh nghiệp nên sử dụng PBI?
- K KICC HCMC x TOPDEV – Bước đệm nâng tầm sự nghiệp cho nhân tài IT Việt Nam
- T Trello là gì? Cách sử dụng Trello để quản lý công việc
- T TOP 10 SỰ KIỆN CÔNG NGHỆ THƯỜNG NIÊN KHÔNG NÊN BỎ LỠ
- T Tìm hiểu Laptop AI – So sánh Laptop AI với Laptop thường
- M MySQL vs MS SQL Server: Phân biệt hai RDBMS phổ biến nhất
- S SearchGPT là gì? Công cụ tìm kiếm mới có thể đánh bại Google?