babel和webpack結合?
npx babel src --out-dir dist --presets=@babel/preset-env
這是把src下面的東西都用babel轉化一下
webpack可以和babel結合使用,首先下載一個這東西:
npm install babel-loader -D
?webpack配置:
const path = require('path');module.exports = {mode: 'development',entry: './src/index.js',output: {path: path.resolve(__dirname, './build'),filename: 'bundle.js',//重新打包時現將之前打包的文件夾刪除clean:true},module:{rules:[{test:/\.js$/,use:{loader:'babel-loader',options:{plugins:['@babel/plugin-transform-arrow-functions','@babel/plugin-transform-block-scoping']}}}]}
}
?要指定對應的插件才生效
如果我們一個個的去安裝使用插件就需要手動管理大量的babel插件,我們可以直接給webpack提供一個preset,webpack會根據對應的預設來加載插件列表并將其傳遞給babel
比較常見的預設有env、react、TypeScript
安裝preset-env:
npm install @babel/preset-env
?瀏覽器兼容性
瀏覽器的內核都趨向于使用Blink
我們在編寫css和js的時候需要考慮到瀏覽器的兼容性問題,但是對于前端開發者來說既要寫代碼又要考慮兼容性就很煩,所以急需一些工具幫助對css/js進行轉化
對css進行轉化的是postcss
對js進行轉化的是babel
而代碼要不要自動進行轉化取決于要適配的瀏覽器,一個一個對應版本還是太麻煩了
編寫一個browserslistrc配置文件可以幫助我們進行瀏覽器適配
也得是配讓我適配的瀏覽器我才會給他適配
哪個熱門人用的多就挑哪個
怎么知道哪個瀏覽器人用的多呢?看瀏覽器市場占有率:
"Can I use" usage tablehttps://caniuse.com/usage-table
超過百分之一的人用就需要做兼容了
?寫好配置就可以用Browserslist做兼容了(在不同的前端工具之間共享目標瀏覽器和Node.js版本的配置)
在開發中我們可以編寫的條件:
配置browserslist可以配置 package.json也可以單獨的一個配置文件.browserslistrc文件
?沒有配置也有默認配置,當編寫了多個條件之后,多個條件之間的關系:
const path = require('path');module.exports = {mode: 'development',entry: './src/index.js',output: {path: path.resolve(__dirname, './build'),filename: 'bundle.js',//重新打包時現將之前打包的文件夾刪除clean:true},module:{rules:[{test:/\.js$/,use:{loader:'babel-loader',options:{// plugins:[// '@babel/plugin-transform-arrow-functions',// '@babel/plugin-transform-block-scoping'// ]presets:["@babel/preset-env",{// 在開發中針對babel的瀏覽器兼容查詢使用browerlist工具,而不是設置targetstargets:">5%"}]}}}]}
}
推薦使用這個工具,不用targets,因為這個工具能進行統一的適配
配置的targets屬性會覆蓋browserslist
Stage-X的preset
ECMAScript規范定義了JavaScript如何一步步的進化、發展
TC39是指技術委員會第39號
特性的打磨發展是一步一步的:
在babel7之前(babel6中),我們經常會看到這種設置方式:
它表達的含義是使用對應的babel-preset-stage-x預設
從babel7開始不建議使用了,建議使用preset-env來設置
Babel的配置文件
我們可以將babel的配置信息放到一個獨立的文件中,babel可以編寫兩種配置文件:
babel.config.json(或者.js , .cjs , .mjs)文件
.babelrc.json(或者 .babelrc , .js , .cjs , .mjs)文件
他們兩個是由區別的:
?認識polyfill
有的時候我們使用了一些語法特性,但是瀏覽器根本不認識這些特性必然會報錯,可以使用polyfill打一個補丁,這樣就包含該特性了
useBuiltlns屬性設置
第三個值就是entry了
如果我們依賴的某一個庫使用了某些polyfill的特性,但是我們使用的是usage之后瀏覽器可能就會報錯
如果擔心出現這樣的情況可以用entry
需要在入口文件添加import 'core-js/stable'
import 'regenerator-runtime/runtime'
這樣做會根據browserslist目標導入所有的polyfill,對應的包也會變大
React的jsx支持
在我們編寫react代碼時,react使用的語法是jsx,jsx是可以直接使用babel來轉換的
對react.jsx處理需要下面的插件:
在開發中不需要一個個的安裝這些插件,依然可以用preset配置
npm install @babel/preset-react -D
配置自動構建:?
{"name": "babel_core_demo","version": "1.0.0","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack"},"author": "","license": "ISC","description": "","devDependencies": {"@babel/cli": "^7.27.2","@babel/core": "^7.27.4","@babel/plugin-transform-block-scoping": "^7.27.5","@babel/preset-env": "^7.27.2","@babel/preset-react": "^7.27.1","babel-loader": "^10.0.0","html-webpack-plugin": "^5.6.3"}
}
然后在webpack里配置babel:
const path = require('path');
const HtmlwebpackPlugin = require('html-webpack-plugin');module.exports = {mode: 'development',entry: './src/index.js',output: {path: path.resolve(__dirname, './build'),filename: 'bundle.js',//重新打包時現將之前打包的文件夾刪除clean:true},resolve: {extensions: ['.js', '.jsx'] // 這句告訴webpack自動嘗試這兩個后綴},module:{rules:[{test:/\.jsx?$/, //表示有0或者1個xuse:{loader:'babel-loader',options:{// plugins:[// '@babel/plugin-transform-arrow-functions',// '@babel/plugin-transform-block-scoping'// ]presets:[["@babel/preset-env", { targets: ">5%" }],"@babel/preset-react"] }}}]},plugins:[new HtmlwebpackPlugin({template:'./index.html',filename: 'end.html' })]
}
這個x?已經能即處理js又處理jsx了
但是莫名其妙還是報錯,加resolve是永遠都搜索這倆文件?
babel的配置文件:
module.exports = {presets: ['@babel/preset-env','@babel/preset-react',],};
模板html:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="root"></div>
</body>
</html>
index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './react/App'
//const定義常量(ES6)
const message = 'Hello World';
console.log(message);const foo = ()=>{console.log("foo function exec!");
}
foo();// 使用字符串中的includes方法
const nickname = 'coderwhy';
console.log(nickname.includes('why'));const root = ReactDOM.createRoot(document.querySelector('#root'));
root.render(<App />);
最后運行webpack就會打包并且react能成功解析運行在瀏覽器中了
ts-loader處理ts代碼
npm install ts-loader -D
需要安裝一下ts:
npm install -g typescript
然后進行初始化:
tsc --init
初始化后直接生成一個tsconfig.json
?然后直接運行npm run build就可以完成編譯了
使用babel-loader
除了可以使用tsc來編譯TS,我們也可以使用Babel
Babel是有對TS進行支持
可以使用插件:@babel/transform-typescript
更推薦直接使用preset:@babel/preset-typescript
ts-loader和babel-loader的選擇
ts-loader默認使用的是TypeScript complier
里面是不包含polyfill的
所以最好用babel-loader
使用針對ts的預設就可以解決這個問題
使用預設的好處是可以配置polyfill
module.exports = {presets: [['@babel/preset-env',{corejs: 3, // 配置使用core-js的版本useBuiltIns: 'usage', // 根據配置的瀏覽器兼容,以及代碼中使用到的 API 進行引入 polyfill 按需加載}],'@babel/preset-react','@babel/preset-typescript',],};
ts-loader會進行類型的校驗,但是babel-loader就不會,所有各有各的優點
建議我們即用babel完成代碼類型的轉化,又使用tsc來進行類型的檢查
但是我們如何使用tsc進行類型的檢查呢?
我們可以在scripts中添加兩個腳本用于類型檢查
執行npm run ts-check可以進行ts類型檢測
執行npm run ts-check-watch可以實時檢測類型錯誤
{"name": "babel_core_demo","version": "1.0.0","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1","build": "webpack","ts-check":"tsc --noEmit","ts-check-watch":"tsc --noEmit --watch"},"author": "","license": "ISC","description": "","devDependencies": {"@babel/cli": "^7.27.2","@babel/core": "^7.27.4","@babel/plugin-transform-block-scoping": "^7.27.5","@babel/preset-env": "^7.27.2","@babel/preset-react": "^7.27.1","babel-loader": "^10.0.0","html-webpack-plugin": "^5.6.3","ts-loader": "^9.5.2"},"dependencies": {"@babel/preset-typescript": "^7.27.1"}
}