最近は業務では自分で開発することがほとんどなくなってしまい、時流が分からなくなってしまった。
プライベートでなんかアプリ作って最近の流行りをキャッチアップしてみる。
npxってなんだ
とりあえずReactのドキュメントを読んでいて。注釈にも入っている。
どうやらrun-scriptを書かなくてもローカルのnode_moduleのバイナリを参照したり、インストールしていないものを一時的に使えるようになるらしい。
グローバルとローカルが異なるときとかは便利かも。
スクラッチで環境をつくる
CreateReactApp使ってしまうとモック作るのはいいけど細かいところの設定で結局ばらすので環境は自前で作りたい。
作った環境は下記で公開
https://github.com/umema4/react16_babel7_webpack4
公式からリンクされている記事を読んで環境構築
https://blog.usejournal.com/creating-a-react-app-from-scratch-f3c693b84658
初期設定
.gitignoreとREADMEは作成済み
npm init
mkdir public src
publicディレクトリに起点となるindex.htmlの作成
code public/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>React Starter</title>
</head>
<body>
<div id="root"></div>
<script src="../dist/bundle.js"></script>
</body>
</html>
babelの設定
記事中では7.1になっているけど2020/04ではバージョンがあがっているのでlatestにしておく
npm install --save-dev @babel/core@latest @babel/cli@latest @babel/preset-env@latest @babel/preset-react@latest
インストールされた最新バージョンは下記だった。
+ @babel/cli@7.8.4
+ @babel/preset-env@7.9.5
+ @babel/core@7.9.0
+ @babel/preset-react@7.9.4
babelの設定
code .babelrc
{
"presets": ["@babel/env", "@babel/preset-react"]
}
webpackの設定
記事中では4.19になっているけど2020/04では4.42とあがっていたのでこちらもlatestdで。
npm install --save-dev webpack@latest webpack-cli@latest webpack-dev-server@latest style-loader@latest css-loader@latest babel-loader@latest
インストールされた最新バージョンは下記だった。
css-loaderが1.0=>3.5とえらい上がっている。
ベースの記事が2018/04。css-loaderのreleaseログみたら2018/12にv2がでてそこからいろいろと上がっている模様。
この先の設定で気を付けたほうがよいかも
+ style-loader@1.1.3
+ webpack-cli@3.3.11
+ webpack-dev-server@3.10.3
+ webpack@4.42.1
+ css-loader@3.5.2
+ babel-loader@8.1.0
webpack.configの設定。特に以前と変わっているところは無さそう。
code webpack.config.js
const path = require('path');
const webpack = require('webpack');
module.exports = {
entry: './src/index.js',
mode: 'development',
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
options: {
presets: ['@babel/env']
}
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
output: {
path: path.resolve(__dirname, 'dist/'),
publicPath: '/dist/',
filename: 'bundle.js'
},
devServer: {
contentBase: path.join(__dirname, 'public/'),
port: 3000,
publicPath: 'http://localhost:3000/dist/',
hotOnly: true
},
plugins: [new webpack.HotModuleReplacementPlugin()]
};
Reactの設定
記事ではReact v16.5。このあたりから触っていないような。。。
最新だとv16.13なので環境以外にも機能面での差分を確認する必要がある。
npm install --save react@latest react-dom@latest
+ react@16.13.1
+ react-dom@16.13.1
エントリーポイントの設定
code src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
ReactDOM.render(<App />, document.getElementById('root'));
ためにしに読み込ませるcomponentの作成
code src/App.js
import React, { Component } from 'react';
import './App.css';
class App extends Component{
render(){
return(
<div className='App'>
<h1> Hello, World! </h1>
</div>
);
}
}
export default App;
CSSファイルも作る
code src/App.css
.App {
margin: 1rem;
font-family: Arial, Helvetica, sans-serif;
}
起動スクリプトの追加
package.jsonに追加する
"scripts": {
"start": "webpack-dev-server --mode development"
},
あれ、npm script書いたほうが余計な記述少なそうだし、npx を使うパターンが見えない。。。
実行
npm run start
下記に接続できることを確認
http://localhost:3000/
この後、記事ではreact-hot-loader使うようにしているけどJSのコードにhotとか入れたくなかったのでwebpack dev serverの設定を変える。
reloadしてもかまわないのでhotOnlyをhotに変更
devServer: {
contentBase: path.join(__dirname, 'public/'),
port: 3000,
publicPath: 'http://localhost:3000/dist/',
- hotOnly: true
+ hot: true
},
ファイルの出力
dev server使っているので出力はされないので、ファイルと出力する部分も確認。
下記を追加
"scripts": {
"build": "webpack --mode production"
}
distディレクトリがができていることを確認。
記事の記述はだいたいこれで終わりだけど、開発するのに足りないところを追加。
SourceMapを用意する
SourceMapがないとデバッグ面倒なのでSourceMapの設定を追加。
これも変わらずdevtoo: trueでよい模様。
ついでにprodの判定も追加しておく。
https://webpack.js.org/configuration/devtool/
const isDebug = process.env.NODE_ENV !== 'production';
console.log(`debug is ${isDebug}`);
module.exports = {
mode: isDebug ? 'development' : 'production',
devtool: isDebug ? 'source-map' : false,
これでreactを動かす環境は整った。次はLint系。
Lintの設定
eslint-config-airbnb
自分がメインで使っていたのはeslint-config-aribnb
repositoryを見るとまだactive。
調べると最近はPrettierなるものが流行っているらしい。eslint --fixだけでは足りないようだ。
こっちもeslint-config-prettierというものがあるとのこと。
star数をみるとairbnbのほうがまだ圧倒しているのでairbnbを使い修正にprettierを使うのでよさそうな気がする。
まずはUsageに従ってeslint-config-airbnbを導入
https://github.com/airbnb/javascript/tree/master/packages/eslint-config-airbnb
npx install-peerdeps --dev eslint-config-airbnb
おお。npxを使うタイミングが来た。
上のコマンドでdevDevenenciesに全部追加されてる。これは楽。
+ eslint-plugin-react@7.19.0
+ eslint-config-airbnb@18.1.0
+ eslint@6.8.0
+ eslint-plugin-react-hooks@2.5.0
+ eslint-plugin-import@2.20.2
+ eslint-plugin-jsx-a11y@6.2.3
babel-eslintからbabel-eslint-parserのはずが。。。
babelの設定忘れてた
babel-eslintの公式見たらbabelのmorepoに統合されてた。
https://github.com/babel/babel/tree/master/eslint/babel-eslint-parser
npm install --save-dev @babel/eslint-parser
installできないorz
npm ERR! 404 Not Found - GET https://registry.npmjs.org/@babel%2feslint-parser - Not found
npm ERR! 404
npm ERR! 404 '@babel/eslint-parser@latest' is not in the npm registry.
仕方ないので従来のbabel-eslintを入れる
npm install --save-dev babel-eslint
eslintはとりあえず初期として下記を設定
{
"extends": [
"airbnb"
],
"parser": "babel-eslint",
"env": {
"browser": true,
"node": true,
"es6": true
}
}
とりあえずnpm scriptを追加して実行
"eslint": "eslint ./src",
なんかエラーでた。
Warning: React version not specified in eslint-plugin-react settings. See https://github.com/yannickcr/eslint-plugin-react#configuration .
eslintrcでreactのバージョンの設定が必要とのこと
"settings": {
"react": {
"version": "detect", // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
// It will default to "detect" in the future
},
prettier
次はprettierを入れる
調べた感じ下記のものを入れておくのが良さそう
npm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier pretty-quick
+ pretty-quick@2.0.1
+ eslint-config-prettier@6.10.1
+ prettier@2.0.4
+ eslint-plugin-prettier@3.1.3
pretty-quickは変更されたファイルだけprettierを実行するので余計なことが起きない模様
eslintをアップデート
https://github.com/prettier/eslint-config-prettier
によるとairbnbと併用する場合はextendsでprettier/reactを設定する必要があるとのこと
eslint-plugin-prettierも入れてあるのでこんな感じか
+ "plugins": ["prettier"],
"extends": [
+ "plugin:prettier/recommended",
+ "prettier/react""
],
試しに実行するとエラーが出た。
1:34 error Replace `'react'` with `"react"` prettier/prettier
2:8 error Replace `'./App.css'` with `"./App.css"` prettier/prettier
4:28 error Insert `・` prettier/prettier
5:11 error Insert `・` prettier/prettier
6:11 error Insert `・` prettier/prettier
7:22 error Replace `'App'` with `"App"` prettier/prettier
single quotationとdouble quotationのエラーが出ている。これはsingleにしておきたいのでルールを変えたい
eslintに下記を追加
"rules": {
"prettier/prettier": [
"error",
{
"singleQuote": true
}
]
}
fixのscriptを追加。自動で修正されると何が変わったかがわからなくなるので把握しておきたい
eslint-plugin-prettierを入れてあるので下記でまとめて修正がかかる(と理解している)
"eslint:fix": "eslint --fix ./src",
エラーが修正されることを確認
CSS loaderは何か変わったのか
前述の通り、CSS loaderのバージョンが大きく変わっている。
release note見ると大き目の話は
- cssの中でimportができるようになってる
- urlの扱いが変わったぽい
- @valueで変数定義できるようになった
というところだろうか
個人的には従来通りlocal使ってscope管理できる設定が使えればそこまで困らない。
CSS modulesを有効にする必要がある。
下記の設定を追加
{
loader: 'css-loader',
options: {
modules: true,
},
},
こんな感じになる。
<div class="_1o-FpbQrR11SDFN-G7O4U3"><h1> Hello, World! </h1></div>
debugしにくいのでlocalIdentNameを設定。設定方法が以前と変わっていた。modulesに追加するようになったようなので
下記のように変更
{
loader: 'css-loader',
options: {
modules: {
localIdentName: isDebug
? '[path][name]__[local]'
: '[hash:base64:8]',
},
},
},
指定したclassがわかるようになった
<div class="src-App__App"><h1> Hello, World! </h1></div>
自分の以前のprojectみたらpostcss-loaderも使っていた。
css-nanoを設定している。
githubの更新は2年くらい止まっているみたい。
cssnanoの公式では
Webpack
You can use cssnano explicitly with postcss-loader.
とされているのでそのまま設定するのでよさそう
npm install --save-dev cssnano postcss-loader
z-indexはいじることあるので下記の設定しておく
css-loaderでsourcemap有効にしておけばcasnano使ってもたどれるのでpostcssでは設定不要のようだ
{
loader: 'postcss-loader',
options: {
plugins: () => [
require('cssnano')({
zindex: false,
}),
],
},
},
style-lintも入れておく
npm install --save-dev stylelint stylelint-config-recommended
code .stylelintrc.json
{
"extends": "stylelint-config-recommended"
}
lint実行したらエラーが発生。versionは13.3.2
const { isPathValidisPathValid } = require('ignore').default;
TypeError: Cannot destructure property 'isPathValid' of 'require(...).default' as it is undefined.
バージョン変えるとstylelint12はOKで13はNG
nodeのサポートが変わった影響?手元の環境はnode12なのだがisPathValidisPathValidがなくなったのだろうか
とりあえずstylelint@12.0.1を入れておく
css-loadでlocalを設定するようにしたのでselector-pseudo-class-no-unknownのエラーが発生
ruleを追加しておく
"selector-pseudo-class-no-unknown": [true, {
"ignorePseudoClasses": ["local"]
}]
出力ファイルを分割しておく。
3rd partyと自前のものを分割しておきたいので下記の設定を導入
https://webpack.js.org/plugins/split-chunks-plugin/#split-chunks-example-2
before
Asset Size Chunks Chunk Names
bundle.js 1.33 MiB main [emitted] main
bundle.js.map 1.53 MiB main [emitted] [dev] main
after
Asset Size Chunks Chunk Names
bundle.js 66.4 KiB main [emitted] main
bundle.js.map 63.2 KiB main [emitted] [dev] main
vendors.bundle.js 1.27 MiB vendors [emitted] vendors
vendors.bundle.js.map 1.47 MiB vendors [emitted] [dev] vendors
precommitフック
flowtype
テスト系が残っているけどとりあえず動かせる環境はやっと用意できた。
知らなったReactの機能
react-hooks
commit前にlint実施してエラーがあればcommitしないようにする。
自動でfixまでしてまうと自分でわからなくなりそうなのでlintまでにしておく
npm i --save-dev husky lint-staged
lint-stagedの書き方変わってる。lintersが不要になってる。
brfore
"lint-staged": {
"linters": {
"*.js": "eslint",
"*.css": "stylelint"
},
},
after
"lint-staged": {
"*.js": "npm run eslint",
"*.css": "npm run stylelint"
},
1件のコメント