js
,css
,html
代碼的過程ts
—>js
,less
/scss
—>css
等)js
,css
,html
代碼;壓縮合並圖片等)注:若是你是初學者,但願你能跟着個人步驟操做一下css
npm install webpack --save-dev
)webpack-cli
(npm install webpack-cli --save-dev
),以便解析用戶傳參(核心yargs
)src
文件夾並在其中建立index.js
文件
// index.js
console.log('hello webpack')
複製代碼
npx webpack
main.js
文件的dist
文件夾;同時你也必定注意到瞭如上圖中紅框所圈出的WARNING
,是由於咱們沒有指定mode
(模式:包含生產(production
)和開發(development
)兩種),不傳會默認production
模式npx webpack --mode development
WARNING
,比較一下此時main.js
和以前的區別src
文件夾中再建立一個other.js
,在index.js
經過require
引入// other.js
module.exports = 'hello webpack'
// index.js
const other = require('./other.js')
console.log(other)
複製代碼
npx webpack --mode development
dist
文件夾下建立一個index.html
文件並引入產生的main.js
文件,在瀏覽器中查看index.html
的console
index.html
中直接引入src
文件夾下的index.js
,在瀏覽器中查看index.html
的console
後者的緣由是由於咱們的瀏覽器不支持
coomonjs
,這裏我不作過多解釋;咱們來分析一下前者是如何實現的html
// 刪除掉冗餘部分的main.js文件
(function (modules) {
var installedModules = {};
function __webpack_require__(moduleId) { // ./src/index.js ./src/other.js
if (installedModules[moduleId]) { // 相似Commonjs中的緩存處理
return installedModules[moduleId].exports;
}
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
};
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
module.l = true;
return module.exports;
}
return __webpack_require__("./src/index.js");
})
({
"./src/index.js":
(function (module, exports, __webpack_require__) {
// 默認會調用 require("./src/other.js")
eval("const other = __webpack_require__(\"./src/other.js\");console.log(other);");
}),
"./src/other.js":
(function (module, exports) {
eval("module.exports = 'hello webpack';");
})
});
/* webpack打包流程 * 1.找到入口文件(index.js) * 2.找到入口文件中的依賴模塊(other.js) ast解析加載依賴模塊 * 3.從入口文件開始執行 require方法改寫成 __webpack_require__ * 內部本身實現了一個Commonjs模塊(須要找到入口,須要找到入口中的全部依賴,加載依賴 + 模板——>渲染後的結果) */
複製代碼
真正的開發中咱們確定不會零配置打包,確定根據咱們的須要來手動配置
webpack
node
webpack.config.js
或webpackfile.js
文件。(本文以webpack.config.js
爲例)
webpack.config.js
(採用coomonjs
規範)// webpack.config.js
module.exports = { // 導出一個對象;對象中放置配置;會調用這個配置進行構建
}
複製代碼
src
文件夾下index.js
文件名爲guYan.js
,執行npx webpack --mode development
,報錯顯示找不到入口文件
webpack.config.js
文件中增長入口的位置,並執行npx webpack --mode development
;無報錯// webpack.config.js
module.exports = {
entry: './src/guYan.js' //當前入口文件的位置
}
複製代碼
注:咱們能夠經過執行
npx webpack --mode development
時增長config
參數來實現修改默認配置文件webpack.config.js
的名字。好比咱們如今修改webpack.config.js
文件名爲webpack.guYan.js
而後執行npx webpack --mode development --config webpack.guYan.js
效果和以前同樣react
webpack.config.js
文件中增長出口文件的配置,並執行npx webpack --mode development
,效果如圖// webpack.config.js
const path = require('path');
module.export = {
entry: './src/guYan.js',
output:{ // 配置當前出口文件
filename: 'bundle.js', // 出口文件名
path: path.resolve(__dirname,'./build') // 出口目錄,該配置項必須是絕對路徑,默認dist目錄
}
}
複製代碼
HTML
模板public
目錄,並在其中建立index.html
文件
html-webpack-plugin
插件(npm install html-webpack-plugin --save-dev
)
html
webpack.config.js
文件中增長HTML
模板的配置(使用html-webpack-plugin
插件)// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');// 1.引入插件
module.exports = {
entry:'./src/guYan.js',
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'./build')
},
plugins:[ // 2.在plugins中註冊插件
new HtmlWebpackPlugin({
template:'./public/index.html', // 指定模板
filename:'gy.html' // 指定打包後的文件名,默認爲index.html
})
]
}
複製代碼
npx webpack --mode development
,輸出文件目錄如圖,而且你會發如今輸出的gy.html
中自動引入了打包後的bundle.js
npx webpack --mode production
會發現打包後的bundle.js
被壓縮,可是gy.html
沒有被壓縮,還有就是引用的文件一直是一個咱們不清楚會不會出現緩存的問題,這上線確定是不容許的啊,因此咱們須要繼續配置// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.export = {
entry:'./src/guYan.js',
output:{
filename:'bundle.js',
path:path.resolve(__dirname,'./build')
},
plugins:[
new HtmlWebpackPlugin({
template: './public/index.html',
filename:'gy.html',
minify:{ // 配置壓縮形式
removeAttributeQuotes: true, // 刪除全部屬性的引號
collapseWhitespace: true // 刪除全部空白
},
hash:true // 每次引用js文件都加入哈希戳
})
]
}
複製代碼
npx webpack --mode production
後對比以前的效果查看mode
(模式)mode
參數,其實沒有必要這麼麻煩,咱們能夠在webpack.config.js
中配置mode
;執行npx webpack
結果和上文同樣// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports= {
mode: 'production', // 默認兩個參數 development production
entry: './src/guYan.js',
...
}
複製代碼
clean-webpack-plugin
(清理文件夾)在開發構建的過程當中咱們更但願在打包後的文件夾中一直是最新的打包文件,即先刪除掉以前打包產生的文件夾及文件webpack
clean-webpack-plugin
(npm install clean-webpack-plugin --save-dev
)webpack.config.js
文件中進行配置// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clearn-webpack-plugin'); // 1.引入插件
module.exports = {
mode:'development',
entry: './src/guYan.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname,'./build')
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'gy.html',
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true
},
hash:true
}),
/*清空文件的插件*/
new CleanWebpackPlugin({ // 2.註冊插件
cleanOnceBeforeBuildPatterns:['**/*'], // 匹配目錄下的全部文件清空,默認也是全部
})
]
}
複製代碼
webpack.config.js
中的entry
的值都是一個路徑字符串的格式('./src/guYan.js'
),當咱們的入口只有一個的時候咱們這樣寫ok,可是當咱們須要同時打包多個文件的時候呢?咱們如何處理呢?對的,它的值還能夠是個對象guYan2.js
// src/guYan2.js
console.log('I am GuYan');
複製代碼
webpack.config.js
中修改咱們的配置,並執行npx webpack
打包後的文件夾變化效果// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
mode:'development',
entry:{ // 配置多入口
index:'./src/guYan.js',
other:'./src/guYan2.js'
},
output:{
filename: '[name].js',// 爲了響應多入口出口文件名須要動態建立,保證每一個入口都有輸出
path: path.resolve(__dirname,'./bundle')
},
plugins:[
new HtmlWebpackPlugin({
template:'./public/index.html',
filename:'index.html',
minify:{
removeAttributeQuotes:true,
collapseWhitespace:true
},
hash:true
}),
new CleanWebpackPlugin({
clearnOnceBeforeBuildPatterns:['**/*']
})
]
}
複製代碼
html
文件引入打包後的js
文件不出現緩存給咱們形成的困擾,咱們在使用html-webpack-plugin
的時候配了一個hash
,咱們也能夠在出口文件名的位置加入[contentHash]
參數// webpack.config.js
...
output:{
filenama:'[name].[contentHash:8].js' // :後面的是表明長度
}
...
複製代碼
js
文件一個html
文件中引用了兩個js
文件,那若是咱們想分別引用呢?怎麼處理?對的,再new
一次html-webpack-plugin
。因此咱們寫一個循環來處理一個plugin
須要屢次引用的問題// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
let htmlPlugins = ['index','other'].map(chunkName=>(new HtmlWebpackPlugin({
filename:`${chunkName}.html`,
chunks:[chunkName] // 保證按需引入 即index.html文件只引入index.js;other.html只引入other.js
})));
modeule.exports = {
mode:'development',
entry:{
index:'./src/guYan.js',
other:'./src/guYan2.js'
},
output:{
filename:'[name].[contentHash:8].js',
path:path.resolve(__dirname,'./build')
},
plugins:[
new CleanWebpackPlugin(),
...htmlPlugins
]
}
複製代碼
devServer
(webpack-dev-server
)在開發過程當中咱們更但願的是咱們一邊修改代碼頁面自動更新,固然這種處理咱們有兩種方案一個是經過編譯的時候傳入
--watch
不推薦使用(因此我就不作介紹了),另外一種就是經過webpack-dev-server
來啓動,這種方式不會產生構建好的文件,而且會給咱們啓動一個服務css3
注:本小節的例子咱們採用單入口輸入,示例以下web
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
let htmlPlugins = ['index'].map(chunkName=>(new HtmlWebpackPlugin({
filename:`${chunkName}.html`,
chunks:[chunkName]
})));
module.exports = {
devServer:{
port:3000, //指定端口號
open:true, // 是否自動打開瀏覽器
compress:true, // 是否啓用gzip壓縮
contentBase:'./dist' // 指定啓動靜態服務的文件目錄
// 經過webpack-dev-server打包的結果放到內存中,並且目錄是當前的根目錄
},
mode: 'development',
entry: {
index: './src/guYan.js',
},
output: {
filename: '[name].js',
},
plugins: [
new CleanWebpackPlugin({
cleanOnceBeforeBuildPatterns: ['**/*']
}),
...htmlPlugins,
]
}
複製代碼
npx webpack-dev-sever
啓動來查看結果loader
webpack
只能理解 JavaScript
和 JSON
文件。loader
讓 webpack
可以去處理其餘類型的文件,並將它們轉換爲有效 模塊,以供應用程序使用,以及被添加到依賴圖中。enforce:'pre'
)、普通(enforce:'normal'
)、後置(enforce:'post'
)css
style
文件夾,並在其中建立一個index.css
文件,並在src/guYan.js
中引入
/*index.css*/
body{
background:yellow;
}
複製代碼
css-loader
,style-loader
(npm install css-loader style-loader --save-dev
)
css-loader
將css
文件處理成字符傳形式,經過style-loader
在html
中建立<style>
標籤並將css-loader
處理後的字符串插入其中webpack.config.js
中配置loader
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
let htmlPlugins = ['index'].map(chunkName=>(new HtmlWebpackPlugin({
template:'./public/index.html',
filename:`${chunkName}.html`,
chunks:[chunkName],
minify:{
removeAttributeQuotes:true,
collapseWhitespace:true
},
hash:true
})))
module.exports = {
mode:'development',
devServer:{
port:3000,
open:true,
compress:ture,
contentBase:'./dist'
},
entry:{
index:'./src/guYan.js'
},
output:{
filename:'[name].js'
},
plugins:[
new CleanWebpackPlugin(),
...htmlPlugins
],
module:{
rules:[
{
test:/\.css$/,
use:['style-loader','css-loader']
}
]
}
}
複製代碼
npx webpack-dev-server
結果以下
CSS
相關css-modules
common.css
文件中,而後在咱們js
文件中按需引入;這樣咱們就會遇到css
模塊化的問題(css-modules
),咱們舉例說明如何配置解決這個問題src/guYan.js
,在style
目錄下建立一個common.css
文件// guYan.js
import { other } from './other';
import '../style/index.css';
import commonStyle from '../style/common.css';
let div = document.createElement('div');
div.className = commonStyle.guYan;
div.innerHTML = 'GuYan';
document.body.appendChild(div);
console.log(other);
複製代碼
/*common.css*/
.guYan{
color:red;
}
複製代碼
webpack.config.js
// webpack.config.js
...
module:{
rules:[
{
test:/\.css$/,
use:['style-loader',
{
loader:'css-loader',
options:{
modules:true
}
}
]
}
]
}
...
複製代碼
npx webapck-dev-server
特殊注意:
loader
的順序必定要特別注意,若是就想把style-loader
寫在後面須要在其options
中增長enforce:'post'
參數或者在css-loader
的options
中增長enforce:'pre'
參數npm
css3
增長瀏覽器內核前綴style/common.css
以下/*common.css*/
.guYan{
color: red;
background: green;
transform: rotateY(180deg);
}
複製代碼
postcss-loader
(npm install postcss-loader --save-dev
)postcss-loader
只是一個幹活的,它不知道幹什麼活,因此須要一個東西來告訴它,它須要作的是增長前綴,這個東西就是autoprefixer
,因此咱們安裝autoprefixer
(npm install autoprefixer --save-dev
)postcss-loader
)有了,指揮幹活的(autoprefixer
)也有了,可是呢這個幹活的(postcss-loader
)比較裝X,它要求這個指揮幹活的(autoprefixer
)不能像其餘loader
那樣你隨隨便便在options
對象中指揮我,你必須專門在個人配置文件(postcss.config.js
)中指揮我幹活,因此咱們須要在根目錄下建立一個postcss.config.js
文件postcss.config.js
文件// postcss.config.js
module.exports = {
plugins:[
require('autoprefixer')
]
}
複製代碼
webpack.config.js
// webpack.config.js
...
module:{
rules:[
{
test:/\.css$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
modules:true
}
},
'postcss-loader'
]
}
]
}
...
複製代碼
npx webpack-dev-server
css
預處理器less
,sass
(node-sass
),stylus
loader
less-loader
,sass-loader
,stylus-loader
js
文件
loader
(以less
爲例)// webpack.config.js
...
module:{
rules:[
{
test:/\.less$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
modules:true
}
},
'postcss-loader',
'less-loader'
]
}
]
}
...
複製代碼
css
文件
loader
(以less
爲例)// webpack.config.js
...
module:{
rules:[
{
test:/\.css$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
modules:true
}
},
'postcss-loader',
'less-loader'
]
}
]
}
...
複製代碼
css
樣式上文中提到的樣式,不難發現都是嵌套在
html
文件中的head
裏的<style>
標籤中的,可是在平常的開發中咱們通常都是單獨在xxx.css
文件中寫樣式,而後經過<link>
引入,因此咱們接下來抽離css
樣式吧json
mini-css-extract-plugin
(npm install mini-css-extract-plugin --save-dev
)webpack.config.js
,須要注意的是:
css-loader
處理後的字符串寫到一個指定的文件中,想要使其以<link>
標籤的形式引入,須要配合其自帶的loader
使用,即下文的MiniCssExtractPlugin.loader
MiniCssExtractPlugin.loader
,開發模式使用style-loader
// webpack.config.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');// 引入插件
...
module.exports = {
...
plugins:[
new CleanWebpackPlugin(),
...htmlPlugins,
new MiniCssExtractPlugin({ // 註冊插件
filename:'index.css'//指定抽離的文件名
})
...
],
module:{
rules:[
{
test:/\.css$/,
use:[
// 'style-loader'
MiniCssExtractPlugin.loader, // 配合插件自身loader使用
...
]
}
]
}
}
複製代碼
npx webpack-dev-server
結果以下
css
樣式文件npx webpack --mode production
,查看打包後的文件,你會發現咱們抽離的css
文件並無像js
,html
文件同樣被壓縮,這在咱們上線的時候確定是不容許的,因此咱們須要壓縮它optimize-css-assets-webpack-plugin
(npm install optimize-css-assets-webpack-plugin --save-dev
)webpack.config.js
文件// webpack.config.js
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
...
module.exports = {
...
optimization:{ // 配置優化項
minimizer:[ // 手動指定壓縮項
new OptimizeCssAssetsWebpackPlugin({})
]
}
mode:'production'
...
}
複製代碼
npx webpack
查看結果,發現咱們提取的css
文件已經實現壓縮
js
文件沒有壓縮,這是由於當咱們沒有手動配置壓縮項的時候webpack
內部本身實現了配置其自帶的terser-webpack-plugin
插件進行壓縮,而咱們配置後覆蓋掉了它內部本身的配置,因此咱們須要手動將terser-webpack-plugin
配置到minimizer
中// webpack.config,js
const TerserJSPlugin = require('terser-webpack-plugin'); //webpack的內部插件
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');
...
module.exports = {
...
optimization:{
minimizer:[
new TerserJSPlugin({}),// 手動加上壓縮js
new OptimizeCssAssetsWebpackPlugin({})
]
}
mode:'production'
...
}
複製代碼
npx webpack
查看結果image
文件夾並準備一張guYan.jpg
圖片放入其中src/guYan.js
中引入guYan.jpg
// guYan.js
import url from '../image/guYan.jpg';
...
let img = new Image();
img.src = url;
documnt.body.appendChild(img)
複製代碼
file-loader
(npm install file-loader --save-dev
)
webpack.config.js
//webpack.config.js
...
module.exports={
...
module:{
rules:[
...,
{
test:/\.(jpg|png|gif)$/,
use:'file-loader'
}
]
}
}
複製代碼
npx webpack --mode production
查看打包後的文件,會發現生成一個拷貝的圖片
Icon
之類的咱們更但願它能夠轉化爲base64
的格式壓縮,因此這就須要咱們配置另外一個能夠處理圖片的loader
,url-loader
url-loader
(npm install url-loader --save-dev
)webpack.config.js
// webpack.config.js
...
module.exports={
...
module:{
rules:[
...,
{
test:/\.(jpg|png|gif)$/,
use:{
loader:'url-loader',
options:{
limit:100*1024 // 指定壓縮文件的最大字節,超過最大限制會自動調用file-loader處理
}
}
}
]
}
}
複製代碼
npx webpack --mode production
,查看打包後的文件目錄並無生成拷貝的文件(嘗試修改limit
參數的大下感覺一下變化)特殊注意:字體圖標(
xxx.eot
,xxx.svg
,xxx.ttf
,xxx.woff
,xxx.woff2
)只能用file-loader
數組
若是你給的
limit
過大,也就是說會將大的圖片也會轉成base64
的格式會致使打包的時候會有一個性能的警告提示你文件過大,這樣的時候你能夠給一個performance:false
屬性來使打包的時候忽略性能問題的提示,可是通常咱們上線確定考慮性能的問題的,也就是說咱們通常不會將limit
的值設置過大
js
文件中引用圖片的例子,其實在開發中咱們也有可能直接在html
文件中引用圖片,安裝咱們以前的打包方式你會發現會出現找不到圖片,由於路徑變了,解決這個問題咱們須要配置一個html-withimg-loader
// webpack.config.js
...
{
test:/\.html$/,
use:'html-withimg-loader'
}
...
複製代碼
url-loader
的options
增長publicPath
屬性便可//webpack.config.js
...
options:{
limit:2*1024,
publicPath:'https://juejin.im/user/5b685661e51d4517df153771'
}
...
複製代碼
同理
css``js
增長前綴一個套路
options
中增長outputPath
屬性
css
filename
參數屬性前面配置文件夾的名字
html
html-webpack-plugin
插件的filename
屬性前面配置文件夾的名字
js
output
)裏的filename
屬性前面配置文件夾的名字
npx webpack --mode production
查看打包後的文件變化吧JS
相關JS
高級語法降級(經過babel
一系列包)guYan.js
文件以下// guYan.js
class Animal{
constructor(type){
this.type = type;
}
getType(){
return this.type
}
}
let animal = new Animal('哺乳類');
console.log(animal.type);
複製代碼
babel-loader
,@babel/core
,@babel/preset-env
(npm install babel-loader @babel/core @babel/preset-env --save-dev
)webpack.config.js
// webpack.config.js
...
module.exports={
...,
module:{
rules:[
...,
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env'],// 起指揮loader怎麼幹活的做用
}
},
exclude:/node_module/, // 忽略掉不想用loader處理的文件
include:path.resolve(__dirname,'./src') // 指定須要loader處理的文件
}
]
}
}
複製代碼
npx webpack --mode development
,查看打包後的js
文件,咱們發現,他內部實現了一個_classCallCheck
,來做爲轉化咱們的class
類。// 刪除後冗餘的代碼後的打包文件
(function(modules) {
var installedModules = {};
function __webpack_require__(moduleId) {
if(installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
};
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
module.l = true;
return module.exports;
}
return __webpack_require__(__webpack_require__.s = "./src/guYan.js");
})
({
"./src/guYan.js":
(function(module, exports) {
eval(`function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var Animal =function () { function Animal(type) { _classCallCheck(this, Animal); this.type = type; } _createClass(Animal, [{ key: \"getType\", value: function getType() { return this.type; } }]); return Animal; }(); var animal = new Animal('哺乳類'); console.log(animal.type);`);
})
});
複製代碼
src/otherEs6.js
文件,在其中再用class
定義一個類導出,在src/guYan.js
中引入這個文件,再執行編譯。你會發現他內部實現這個公共的_classCallCheck
代碼,實現了兩次,因此咱們須要提取這個公共的代碼@babel/runtime
,@babel/plugin-transform-runtime
(npm install @babel/runtime @bebel/plugin-transform-runtime --save-dev
)webpack.config.js
文件// webapack.config.js
...
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env'],
plugins:['@babel/plugin-transform-runtime']
}
}
...
複製代碼
npx webpack --mode development
,查看打包後的js
文件,比較兩次有什麼不一樣JS
的一些API
降級處理,如promise
(爲了兼容IE
)@babel/preset-env
+core-js@3
core-js@3
(npm install core-js@3 --save
)webpack.config.js
// webpack.config.js
...
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
preset:[
[
'@babel/preset-env',
{
useBuiltIns:'usage',// 只轉化使用的API
corejs:{version:3}
}
]
]
}
}
...
複製代碼
@babel/polyfill
@babel/plugin-transform-runtime
+@babel/runtime-corejs3
@babel/runtime-corejs3
(npm install @babel/runtime-corejs3
)webpack.config.js
// webapck.config.js
...
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env'],
plugins:[
[
'@babel/plugin-transform-runtime',
{
"absoluteRuntime": false,
"corejs": {version:3},
"helpers": true,
"regenerator": true,
"useESModules": false
}
]
]
}
}
...
複製代碼
像裝飾器和類的屬性這些更高級的須要再去配插件去處理,這裏我就不一一舉例了(
@babel/plugin-proposal-decorators
,@babel/plugin-proposal-class-properties
)
ESlint
相關eslint
,eslint-loader
(npm install eslint eslint-loader --save-dev
)webpack.config.js
// webpack.config.js
...
test:/\.js$/,
use:'eslint-loader',
enforce:'pre' // 強制在編譯以前執行
...
複製代碼
eslint
npx eslint --init
webpack.config.js
// we
複製代碼
ts-loader
tsconfig.json
plugin
和loader
的原理及實現create-react-app
實現一個簡單的腳手架注: 參考文檔