首頁 > tools > webpack > > 正文

webpack4從零開始搭建react與vue工程過程實錄

點擊:

webpack4+babel7+react||vue相關工程,網上的教程實在很多,但是,適合自己的,總是感覺還是自己搭建好。webpack4還是需要n多優化部分,配置下來,實為不易。而實際開發也不需要浪費這個時間——了解即可—自以為

react工程:https://github.com/zhoulujun/wepack4-react-project-template

vue工程:https://github.com/zhoulujun/webpack4-vue2-project-template


webpack 一直以來最飽受詬病的就是其配置門檻極高,配置內容極其復雜和繁瑣,容易讓人從入門到放棄,而它的后起之秀如 rollup、parcel 等均在配置流程上做了極大的優化,做到開箱即用,所以webpack 4 也從中借鑒了不少經驗來提升自身的配置效率。愿世間再也不需要 webpack 配置工程師。

但是,webpack4還是需要n多優化部分,配置下來,實為不易。而實際開發也不需要浪費這個時間——了解即可 

啟動:

npm run start

打包:

npm run build
重要包提示
  • 生成manifest.json 離線比對 webpack-manifest-plugin

  • 自動上傳服務器發包 webpack-sftp-client

  • 生成html5 integrity webpack-subresource-integrity

  • 多線程處理 happypack

  • 圖片壓縮 image-webpack-loader

  • js語法檢查 eslint

  • sass預處理 node-ass

  • css兼容補全 autoprefixer

  • 測試框架 karma mocha jasmine

目錄結構

  • src //工程目錄

    • actions

    • components

    • containers

    • images

    • reducers

    • router

    • stores

    • styles

    • untils

  • test //測試目錄

  • dist //打包目錄

  • coverage //測試報告目錄

團隊規范

遵從平臺發布前端規范標準,節選以下要點:

命名規范

遵從Camel命名

變量命名規范:

js規范,請遵從eslint

  • 常量全部大寫,單詞間下劃線分隔

  • 類采用Pascal命名

scss 規范

  • css 按照工程結構 嵌套書寫,嵌套層級不超過三層——采用 @at-root

  • 非頁面引用scss文件,加前綴 _ 如:_fun.scss _mixin.scss

構建過程 節選關鍵步驟

構建目錄初始化

mkdir yourFileNamecd yourFileName

根據工程目錄結構,構建相關文件 ……


npm init 
npm install webpack webpack-cli  --save-dev
注:--save-dev和--save的區別:

development很明顯就是我們開發所需要的依賴包,而打包好上線的話是不需要這些包的,一來各種包加起來太大,二來它只是我們開發提高效率的工具而已; 由于本工程只在本地跑,最終還是sftp自動dist 到服務器,所以暫略

修改package.json ,npm run dev 檢查打包結果

{ "scripts": {   "dev": "webpack --mode development",    "build": "webpack --mode production"
  }
}
注:webpack4只需要一個--mode選項 指定 production||development

參考http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html +如果是并行執行(即同時的平行執行),可以使用&符號。 +如果是繼發執行(即只有前一個任務成功,才執行下一個任務),可以使用&&符號。 npm run script1.js & npm run script2.js npm run script1.js && npm run script2.js


配置webpack配置文件 webpack.config.js

rule對象參數說明
  • test: A condition that must be met 必須滿足的條件

  • exclude: A condition that must not be met 不能滿足的條件

  • include: A condition that must be met 必須滿足的條件

  • loader: A string of “!” separated loaders 用 “!”分割loaders

  • loaders: An array of loaders as string loaders的字符串數組

基礎loader

npm install  css-loader style-loader  html-loader url-loader file-loader --save-dev
    [
                   {
                       test: /\.html$/,
                       use: 'html-loader'
                   },
                   {
                       test: /\.css$/,
                       use: [
                           {
                               loader: 'style-loader',
                               options:{                                   // singleton:true //處理為單個style標簽
                               }
                           },
                           {
                               loader: 'css-loader',
                               options:{                                   // minimize:true //壓縮css
                               }
                           }
                       ]
                   },
                   {
                       test:/\.(png|jpg|jpeg|gif)$/,//圖片處理
                       use:[
                           {
                               loader: 'url-loader',
                               options:{
                                   limit:2048,
                                   name:'[name][hash].[ext]'
                               }
                           },
                           {
                               loader: 'file-loader',
                               publicPath:publicPath,
                               outputPath: 'dist/',
                               useRelativePath: true
                           }
                       ]
                   },
                   {
                       test: /\.(woff|woff2|eot|ttf|otf)$/,//字體處理
                       use: ['url-loader']
                   },

    ]

配置babel 編譯js

npm install --save-dev  babel-loader @babel/core  @babel/preset-env 
npm install --save-dev  eslint-loader
    [
        {
            test: /\.js$/,
            loader: 'babel-loader',
            exclude: /node_modules/ //設置node_modules里的js文件不用解析
        }
    ]

參考:https://segmentfault.com/a/1190000010468759

babel7.0后,需要@ @babel/core vs babel-core babel插件和版本需要對應上,不然掉坑 參考https://www.w3ctech.com/topic/2150 babel-preset-es2015 babel-plugin-transform-runtime babel-plugin-add-module-exports babel-plugin-transform-runtime babel-plugin-transform-class-properties

.babelrc配置文件
{    "presets": ["@babel/preset-env","@babel/preset-react"]
}

配置eslint 檢查

npm install --save-dev  eslint eslint-loader babel-eslint eslint-plugin-react
[
   {//eslint 檢查
      test: /\.(js|jsx)$/,
      enforce: 'pre',
      loader: ['eslint-loader'],
      exclude: /node_modules/ //設置node_modules里的js文件不用解析
    },
]

增加.eslintrc配置

具體查看 http://www.qsexmk.tw/html/tools/grunt/2016_0519_7832.html

intellij 會自動檢車eslint

處理html

npm install html-webpack-plugin

    new HtmlWebpackPlugin({
            filename: './index.html',//輸出文件
            template: 'src/index.html',//模板文件
            inject: 'body',//插入位置
            chunks: ['index'],
            hash: true,
            minify: {
                caseSensitive:false,
                removeComment:true,//移除注釋
                collapseWhitespace:false//移除多余空格
            }
        })
chunks: ['index','vendor','manifest'], 一定要記得 各處的chunk ,特別是optimization.runtimeChunk

處理圖片 - 壓縮圖片

參考:http://shirmy.me/2018/05/15/webpack-圖片、文件處理/

npm install image-webpack-loader --save-dev
    [
        {
            test: /\.(png|jpg|jpeg|gif)$/i,//圖片處理
            use: [
                {
                    loader: 'url-loader',
                    options: {
                        limit: 0,//圖片不轉base64,增加css的阻塞時間,開啟http2,所以也不用雪碧圖
                        name: '[name].[hash:5].[ext]',
                    }
                },
            ]
        },
        {//壓縮圖片
            loader: 'image-webpack-loader',
            options: {
                bypassOnDebug: true,
            }
        },
    ]

配置webapck server

npm install webpack-dev-server open --save-dev

參看 webpack.server.js 注釋

{  "start": "node webpack.server.js"}

npm start 啟動項目

配置css優化設置

npm install --save-dev postcss-loader autoprefixer postcss autoprefixer  mini-css-extract-plugin
注:
  • webpack4已經廢棄 extract-text-webpack-plugin 這個插件了,現在使用的是 mini-css-extract-plugin

  • 在項目根目錄新建postcss.config.js文件,并對postcss進行配置:

module.exports = {
    plugins: {        'autoprefixer': {
            browsers: [                "> 1%",                "last 5 versions",                "not ie = 8",                "android >= 4.0"
            ]
        }
    }
};

不然會報出:Error: No PostCSS Config found

自動消除冗余的css代碼

npm install --save-dev  optimize-css-assets-webpack-plugin
css壓縮優化空間不大,nginx開啟gzip的情況,很有限,有點畫蛇添足。但是,聊勝于無吧^_^

配置sass

npm install --save-dev  node-sass sass-loader

webpack構建優化

多線程 happypack

npm install --save-dev  happypack

配置第三方包,比如jquery

npm install imports-loader --save-dev
[
    {
        loader: 'imports-loader',
        options: {            // 模塊為 value,同樣webpack也會解析它,如果沒有則從alias中解析它
            $: 'jquery'
        }
    }
]

增加manifest.json 配置,緩存校對下載, 增加js integrity 安全校驗

npm install --save-dev webpack-subresource-integrity webpack-assets-manifest

兩個插件準備寫成一個,看來不到春節沒有時間

增加webpack 模塊分析

配置參看 webpack.analy 參考文章:https://www.cnblogs.com/ssh-007/p/7944491.html

npm install --save-dev webpack-bundle-analyzer

webpack壓縮js、css文件

npm install --save-dev  webpack-parallel-uglify-plugin optimize-css-assets-webpack-plugin cssnano
const UglifyJsPlugin=require('webpack-parallel-uglify-plugin');const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');const cssnano = require('cssnano');config.optimization = {
  minimizer:[    new UglifyJsPlugin({
      cache: true, // node_modules/.cache/uglifyjs-webpack-plugin
      parallel: os.cpus().length, // 并行 default:true os.cpus().length - 1
      uglifyOptions: {
        ecma: 5,
        mangle: true,
      },
      sourceMap: false,
    }),    new OptimizeCSSAssetsPlugin({
      assetNameRegExp: /\.css$/g,
      cssProcessor: cssnano, // 默認使用 cssnano 處理 css
      cssProcessorOptions: {
        reduceIdents: false, // 禁止將 keyframes 自動更名
        mergeIdents: false, // 禁止自動合并 keyframes
        discardUnused: false, // 禁止移除掉未使用的 keyframes
        autoprefixer: false, // 禁止默認刪除掉一些前綴,以減少兼容性的問題
        zindex: false, // 禁止自動轉換 z-index
        map: false,
      },
    }),
  ],  ...
  
  }

參考:https://jdc.jd.com/archives/212580

Webpack v4 以前使用內置的 webpack.optimize.UglifyJsPlugin 插件,在 Webpack 4 以后,開始使用 ^1.0.0 獨立的版本。

增加上傳至服務器

npm install --save-dev webpack-sftp-client
  new WebpackSftpClient({
      port: '20020',
      host: '10.111.111.38',
      username: 'nginx',
      password: '[email protected]',
      path: './dist/',//本地上傳目錄
      remotePath: '/usr/local/nginx/html/demo',//服務器目標目錄
      verbose: true
  })

配置react

npm install --save-dev react react-dom @babel/preset-react babel-preset-react  eslint-plugin-react

配置react router

npm install --save-dev [email protected] history redux react-redux redux-thunk

react-router v4 官方教程 第一個是:react-router-dom,配置方面的 第二是code-splitting:https://reacttraining.com/react-router/web/guides/code-splitting React-router4簡約教程 https://www.jianshu.com/p/bf6b45ce5bcc [email protected] 2.x 不兼容

react-router4升級踩坑 https://www.jianshu.com/p/56dce67b8b13

推薦 [email protected]

npm install --save-dev   react-router-dom history redux react-redux redux-thunk   react-router-redux
npm install --save-dev react-loading  react-hot-loader
npm install --save-dev es6-promise isomorphic-fetch immutable

測試

Karma文檔 http://karma-runner.github.io/3.0/config/configuration-file.html

  • 測試管理工具 karma

  • 測試框架 jasmine ||mocha&&斷言庫 chai||expect

  • 測試覆蓋率統計工具 Karma-Coverage

  • 測試瀏覽器 PhantomJs||chrome

之前一直是Mocha做測試,后面更喜歡 jasmine,因為之前有個童鞋就叫這個名字

推薦閱讀:https://www.jianshu.com/p/6726c0410650

npm install --save-dev karma karma-coverage karma-mocha karma-mocha-reporter karma-phantomjs-launcher karma-sourcemap-loader karma-webpack
npm install --save-dev karma-jasmine  jasmine-core
npm install --save-dev chai isparta-instrumenter-loader mocha phantomjs-prebuilt react-addons-test-utils
npm install --save-dev  glob minimatch

node的glob模塊允許你使用 *等符號, 來寫一個glob規則,像在shell里一樣,獲取匹配對應規則的文件. 這個glob工具基于javascript.它使用了 minimatch 庫來進行匹配 https://www.cnblogs.com/xinxingyu/p/5736244.html

react-composition //中文輸入問題

webpack 相關優化,可參看:http://www.qsexmk.tw/html/tools/webpack/2016_0218_7492.html

#npm 包簡要說明————待優化

{
  "devDependencies": {
      "@babel/core": "^7.2.2",
      "@babel/preset-env": "^7.2.3",
      "@babel/preset-react": "^7.0.0",
      "autoprefixer": "^9.4.4",//css不全兼容代碼
      "babel-eslint": "^10.0.1",
      "babel-loader": "^8.0.4",
      "chai": "^4.2.0",//斷言庫
      "css-loader": "^2.1.0",
      "es6-promise": "^4.2.5",
      "eslint": "^5.12.0",
      "eslint-loader": "^2.1.1",
      "eslint-plugin-react": "^7.12.3",
      "eslint-plugin-vue": "^5.1.0",
      "file-loader": "^3.0.1",
      "glob": "^7.1.3",
      "happypack": "^5.0.1",//多線程 處理 *-loader
      "history": "^3.2.1", //router  history 處理
      "html-loader": "^0.5.5",
      "html-webpack-plugin": "^3.2.0",//入口 html 合成
      "image-webpack-loader": "^4.6.0",//圖片壓縮
      "immutable": "^4.0.0-rc.12",
      "isomorphic-fetch": "^2.2.1",
      "isparta-instrumenter-loader": "^1.0.1",
      "jasmine": "^3.3.1",//BDD, framework independent, 測試框架 || https://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#JavaScript
      "jasmine-core": "^3.3.0",
      "karma": "^3.1.4",//測試管理工具 ||Selenium、WebDriver/Selenium 2、Mocha[1]、JsTestDriver、HTML Runners和Karma,我這里選擇使用Karma
      "karma-coverage": "^1.1.2",//測試覆蓋報告
      "karma-jasmine": "^2.0.1",
      "karma-mocha": "^1.3.0",
      "karma-mocha-reporter": "^2.2.5",
      "karma-phantomjs-launcher": "^1.0.4",
      "karma-sourcemap-loader": "^0.3.7",
      "karma-webpack": "^3.0.5",
      "mini-css-extract-plugin": "^0.5.0",
      "minimatch": "^3.0.4",
      "mocha": "^5.2.0",//測試框架 || https://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#JavaScript
      "node-sass": "^4.11.0",
      "open": "0.0.5",//打開瀏覽器  chrome-launch 
      "phantomjs-prebuilt": "^2.1.16",
      "postcss": "^7.0.7",
      "postcss-loader": "^3.0.0",
      "react": "^16.7.0",
      "react-addons-test-utils": "^15.6.2",//react官方的測試插件
      "react-dom": "^16.7.0",
      "react-hot-loader": "^4.6.3",
      "react-loading": "^2.0.3",//loading 動畫
      "react-redux": "^6.0.0",
      "react-router": "^3.2.1",//待升級4.x
      "redux": "^4.0.1",
      "redux-thunk": "^2.3.0",//異步套件 ||http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html
      "sass-loader": "^7.1.0",
      "style-loader": "^0.23.1",
      "url-loader": "^1.1.2",//處理url 文件打包
      "webpack": "^4.28.3",
      "webpack-assets-manifest": "^3.1.1",
      "webpack-bundle-analyzer": "^3.0.3",
      "webpack-cli": "^3.2.0",
      "webpack-dev-server": "^3.1.14",
      "webpack-manifest-plugin": "^2.0.4",//生成manifest
      "webpack-sftp-client": "^1.2.1",//上傳服務器
      "webpack-subresource-integrity": "^1.3.1"//生成html5 integrity
    }
}

后記:從grunt glup webpack1.x -3.x ,每次搭建都耗費一番功夫。但是webpack4 跟 react redux router 里面 各個版本不兼容的坑蠻多。比如用用之前最順手的項目環境 套webpack4,搞錯是一丟丟, 干脆重新從0開始搭建,估計半年后,又忘記了!——我始終覺得這個東西,沒有必要太在上面嗑。對里面稍微了解就好。


vue-eslint:

https://eslint.vuejs.org/rules/no-side-effects-in-computed-properties.html

https://mysticatea.github.io/vue-eslint-demo/