<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 一、IE8基礎兼容問題 ### 1.1 CSS兼容 舊引擎不支持太多CSS3特性,在無法使用Flex布局的情況下盡量使用原始的表格排版代替,使用表格基本上不用考慮兼容性問題,事實上,這類人群對界面也沒有什么過分要求。 IE8不支持漸變和透明通道,做全局半透明遮罩的時候尤其蛋疼,DXImageTransform濾鏡雖然能對容器進行著色但不能防止事件穿透,即便是一個全屏著色的遮罩層其背后的各種控件依然是可以點擊的,建議放棄線性漸變,使用小尺寸PNG圖片作為容器背景元素,設置background-repeat進行平鋪。 ### 1.2 JavaScript兼容 ``` * IE8非調試環境下不支持console,執行到console.log之類的代碼會直接報錯,只有調出控制臺時才會生成window.console對象,因此首要引入console-polyfill,具體作用可參見其源代碼。IE8非調試環境下不支持console,執行到console.log之類的代碼會直接報錯,只有調出控制臺時才會生成window.console對象,因此首要引入console-polyfill,具體作用可參見其源代碼。 ``` ### 1.2.1、保留字問題 ECMAScript定義了一套關鍵字和保留字,根據規定,關鍵字是保留的,不能用作變量名或函數名。在實現ECMAScript 3的JavaScript引擎中使用關鍵字作標識符,會導致"Identifier Expected"(缺少標識符)錯誤。而使用保留字作標識符可能會也可能不會導致相同的錯誤,具體取決于特定的引擎。 | break | do | instanceof | typeof | case | else | | --- | --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- | | new | var | catch | finally | return | void | | continue | for | switch | while | debugger | function | | this | with | default | if | throw | delete | | in | try | abstract | enum | int | short | | boolean | export | interface | static | byte | extends | | long | super | char | final | native | synchronized | | class | float | package | throws | implements | protected | | volatile | double | import | public | package | let | | yield | | | | | | ECMAScript 5對使用關鍵字和保留字的規則進行了少許修改。關鍵字和保留字雖然仍然不能作為標識符使用,但可以用作對象的屬性名,IE8自然是不支持新特性的,會將屬性名當作保留字處理,定位“缺少標識符”錯誤時基本上都會指向某個保留字,需要使用插件es3ify-webpack-plugin轉換對象訪問方式,將點運算符訪問改為使用中括號運算符訪問,但該插件似乎并不能在Webpack 4.x上工作。 ` // In var x = {class: 2,}; x.class = [3, 4,]; // Out: var x = {"class": 2}; x["class"] = [3, 4]; ` ### 1.2.2、ECMAScript5 IE8不支持ECMAScript5,不能使用Array.map、Function.bind等方法,引入es5-shim可擴展出大部分ES5 API。 唯一重要且不能模擬的是Object.defineProperty,直接通過變量賦值的方式觸發事件分發,已經超出舊引擎的能力范圍了,像Vue.js這些使用到該特性的第三方庫均不可能兼容IE8。 ~~~ <html> <head></head> <body> <p id="time"></p> <script> // run in internet explorer 9+ var obj = {}; var text = ""; Object.defineProperty(obj, "a", { set: function(newValue) { text = newValue; document.getElementById("time").innerText = text; }, get: function() { return text; } }); setInterval(function() { obj.a = new Date().toString(); }, 1000); </script> </body> </html> ~~~ ### 1.2.3、ECMAScript 6 基本上引入babel-polyfill足夠了,主要是兼容Promise,但要注意引入順序,在進行ES5兼容處理之前引入會報諸如"Promise未定義"之類的錯誤。 # 二、Webpack配置 部分關鍵插件由于兼容問題,Webpack 4.x以上方案暫時無解。 ## 2.1、核心插件 某些插件在Webpack2.x和3.x下具有不同適用性,安裝的時候注意版本號。 | 插件 / 版本 | webpack 2.7.0 | webpack 3.12.0 | | --- | --- | --- | | react | 0.14.9 | 0.14.9 | | react-dom | 0.14.9 | 0.14.9 | | react-router | 1.0.3 | 1.0.3 | | redux | 3.5.2 | 3.5.2 | | webpack-dev-server | 2.11.2 | 2.11.2 | | webpack-dev-middleware | 2.0.6 | 2.0.6 | | webpack-hot-middleware | \>=2.22.2 | \>=2.22.2 | | url-loader | 0.6.2 | \>=1.0.1 | | extract-text-webpack-plugin | 2.1.2 | 3.0.2 | | history | 1.7.0 | 1.7.0 | | es3ify-webpack-plugin | 0.0.1 | 0.0.1 | 測不出版本上限的插件全部用>=標注,可以嘗試用最新版。 react能兼容ie8的最后版本是0.14.9。 redux版本需要<3.6.0,我不清楚3.5.x到3.6.0版本之間發生了什么。 react-router需要<2.0。 webpack-dev-middleware<3.0.0。 至于混淆壓縮插件uglifyjs-webpack-plugin不是必需的,配置不當可能會引起詭異的錯誤,建議持保留態度。 ## 2.2、入口文件 在entry項定義入口文件,其中包含必需的兼容庫,視情況甚至還需要引入jQuery。 main為自定義入口文件,在main.js完成ReactDOM.render等啟動操作,視個人習慣而言。 ~~~ entry: { "console-polyfill": "console-polyfill", "es5-shim": "es5-shim/es5-shim.js", "es5-sham": "es5-shim/es5-sham.js", "babel-polyfill": "babel-polyfill", main: [path.resolve("src", "index.js")] } ~~~ 由于html-webpack-plugin默認注入順序是不可預測的,可能會出現ES6兼容庫執行先于ES5兼容庫的情況。 ~~~ <script type="text/javascript" src="./scripts/babel-polyfill.js?fbe5d7c0c4f12cdfda8c"></script> <script type="text/javascript" src="./scripts/main.js?fbe5d7c0c4f12cdfda8c"></script> <script type="text/javascript" src="./scripts/es5-shim.js?fbe5d7c0c4f12cdfda8c"></script> <script type="text/javascript" src="./scripts/es5-sham.js?fbe5d7c0c4f12cdfda8c"></script> <script type="text/javascript" src="./scripts/console-polyfill.js?fbe5d7c0c4f12cdfda8c"></script> ~~~ 解決辦法之一是不使用entry配置,手動整理出需要加載的靜態資源,然后用標簽在模版文件中依次注入,這樣的話就不需要配置entry了,只留一個入口文件main.js就夠了。 另外一種方法是指定html-webpack-plugin插件的配置項chunksSortMode為"manual",打包時入口文件會按配置項chunks指定的順序注入。 ~~~ plugins: [ new HtmlWebpackPlugin( { template: path.join("src", "index.html"), favicon: path.join("src", "favicon.ico"), minify: false, hash: true, inject: true, chunks: ["console-polyfill", "es5-shim", "es5-sham", "babel-polyfill", "main"], chunksSortMode: "manual" }) ] ~~~ ~~~ <script type="text/javascript" src="./scripts/console-polyfill.js?fbe5d7c0c4f12cdfda8c"></script> <script type="text/javascript" src="./scripts/es5-shim.js?fbe5d7c0c4f12cdfda8c"></script> <script type="text/javascript" src="./scripts/es5-sham.js?fbe5d7c0c4f12cdfda8c"></script> <script type="text/javascript" src="./scripts/babel-polyfill.js?fbe5d7c0c4f12cdfda8c"></script> <script type="text/javascript" src="./scripts/main.js?fbe5d7c0c4f12cdfda8c"></script> ~~~ # 三、CSS Modules * * * Webpack的loader預處理類似于管道,上一個loader的輸出作為下一個loader的輸入,用數組表示就是索引大的loader的輸出作為索引小loader的輸入。 ~~~ { test: /\.less$/, use: [{ loader: "style-loader" // creates style nodes from JS strings }, { loader: "css-loader" // translates CSS into CommonJS }, { loader: "less-loader" // compiles Less to CSS }] } ~~~ ## 3.1、編譯到分離 對于less文件的編譯,less-loader將less文件編譯輸出為css代碼,css代碼中的url會在css-loader中被轉換,樣式代碼隨入口文件一并打包,style-loader在運行時生成標簽,并將樣式代碼注入到標簽中。 為了提高頁面加載效率,還需要使用插件extract-text-webpack-plugin將樣式代碼從入口文件中分離存儲為css文件。 ~~~ const ExtractTextPlugin = require('extract-text-webpack-plugin'); // Create multiple instances const extractCSS = new ExtractTextPlugin('stylesheets/[name]-one.css'); const extractLESS = new ExtractTextPlugin('stylesheets/[name]-two.css'); module.exports = { module: { rules: [ { test: /\.css$/, use: extractCSS.extract([ 'css-loader', 'postcss-loader' ]) }, { test: /\.less$/i, use: extractLESS.extract([ 'css-loader', 'less-loader' ]) }, ] }, plugins: [ extractCSS, extractLESS ] }; ~~~ 無論用什么預處理器,style-loader與css-loader總是固定存在的,配置 也是基本相同的,以至于可以編寫一個模版函數來統一生成這些預處理配置。 ## 3.2、模塊化 css-loader自帶模塊化功能,其實就是混淆,需要指定配置項modules和localIdentName才會生效。 ~~~ { loader: 'css-loader', options: { modules: true, localIdentName: '[path][name]__[local]--[hash:base64:5]' } } ~~~ 模塊機制下的css編寫與傳統方式有些許不同,圖片url是相對源代碼目錄的,經Webpack編譯處理后才會轉為網絡資源路徑,但當使用到less-loader這類預處理器時,這個環節會出錯,css-loader不能處理上一級的輸出,例下less文件: ~~~ .app { background-image: url("./img/pic.png"); .red { color: red; } } .redColor{ color: red; } ~~~ 當啟動模塊化功能時,css-loader會直接提示"Module not found",找不"pic.png",需要在中間加一層resolve-url-loader作轉換,完整的配置如下: ~~~ { test:/\.less$/, use:extractLESS.extract({ fallback:{ loader:"style-loader", options:{ sourceMap:true } }, use:[{ loader:"css-loader", options:{ sourceMap:true, minimize:config.compress, localIdentName:"[name]-[local]-[hash:base64:5]", modules:true } },{ loader:"resolve-url-loader" },{ loader:"less-loader", options:{ sourceMap:true } }], publicPath:"../" }) } ~~~ ## 3.3、全局沖突問題 模塊化解決了全局污染問題,但是也可能導致全局樣式失效,只要途徑同一預處理管道的樣式文件,選擇器名稱無例外都會被混淆,導致與容器的class匹配不上,因此需要把全局作用的樣式文件從模塊化管道中排除掉,最簡單的方法是分開目錄存放,然后修改配置項的正則表達式,通過目錄名稱來過濾。 ~~~ /* In */ .app { background-image: url("./img/pic.png"); .red { color: red; } } /* Out */ .src-components-app-styles---app---1-oEM { background-image: url("./images/pic.png"); } .src-components-app-styles---app---1-oEM .src-components-app-styles---red---12lu- { color: red; } ~~~ ~~~ import React from 'react'; import './app.less'; export default () => { return ( // app -> src-components-app-styles---app---1-oEM <div className="app"> <p className="red">Hello World</p> </div> ); }; ~~~ ### 3.3.1、Solution 1 CSS Modules允許使用:global(.className)的語法,聲明一個全局規則。凡是這樣聲明的class,都不會被編譯成哈希字符串。 ~~~ .title { color: red; } :global(.title) { color: green; } ~~~ CSS Modules還提供一種顯式的局部作用域語法:local(.className),等同于.className,所以上面的css也可以寫成下面這樣。 ~~~ :local(.title) { color: red; } :global(.title) { color: green; } ~~~ ### 3.3.2、Solution 2 通過文件后綴來區分是否是全局作用的樣式文件,擴展名為“.less”則視為全局作用,后綴為“.scope.less”則視為局部作用,通過區分后綴是否包含scope字眼來分開編譯,但正則表達式不擅長“不包含”的識別,不要企圖通過`/(scope){0}.less/`來區分,你會發現路徑沖突根本不會通過編譯。 預處理配置項test除了可以接受正則表達式外,使用回調函數也是可以的,指定一個傳入參數為文件物理路徑的function,通過返回布爾值來代替正則表達式的test操作: ~~~ // custom function const lang= "less"; // lang = "less" 、"sass" ..... const suffix = `.scope.${lang}`; const ext = `.${lang}`; // if path include 'scope.less' function test(path) { return path.lastIndexOf(ext) == path.length - ext.length && path.lastIndexOf(suffix) == path.length - suffix.length; } // webpack config { test:test, use:extractLESS.extract({ fallback:{ loader:"style-loader", options:{ sourceMap:true } }, use:[{ loader:"css-loader", options:{ sourceMap:true, minimize:config.compress, localIdentName:"[name]-[local]-[hash:base64:5]", modules:true } },{ loader:"resolve-url-loader" },{ loader:"less-loader", options:{ sourceMap:true } }], publicPath:"../" }) } ~~~ ### 3.3、classnames插件 JSX書寫className十分繁瑣,可以使用插件classnames簡化操作,具體使用方法參看官方文檔。 [https://github.com/JedWatson/classnames](https://github.com/JedWatson/classnames) [https://www.npmjs.com/package/classnames](https://www.npmjs.com/package/classnames) ~~~ npm: npm install classnames --save Bower: bower install classnames --save Yarn (note that yarn add automatically saves the package to the dependencies in package.json): yarn add classnames ~~~ 模塊機制下,樣式文件導入后實際為一個map: ~~~ { app: "src-components-app-styles---app---1-oEM", red: "src-components-app-styles---red---12lu-", big: "src-components-app-styles---big---Y9ObK" } ~~~ JSX的className只接受字符串,需自行拼接各個鍵值后賦值給className: ~~~ import styles from "app.less" <div className={styles.app+ " " +styles.red}> <p className={styles.red}></p> </div> // or <div className={String.join(styles.app,styles.red," ")}> <p className={styles.red}></p> </div> ~~~ 使用classnames包裝,實質仍然是輸出字符串,但不用寫String.join或加號了: ~~~ import styles from "app.less" import classNames from "classnames"; <div className={classNames(styles.app,styles.red)}> <p className={styles.red}></p> </div> ~~~ 不想書寫“styles.”,可以再進一步包裝: ~~~ import styles from "app.less" import classNames from "classnames/bind"; var cx = classNames.bind(styles); <div className={cx('app','red')}> <p className={styles.red}></p> </div> ~~~ 理解其原理后,甚至可以: ~~~ function bindStyles(styles) { return function(...argv){ let _cx=classNames.bind(styles); let keys=argv.filter((i)=>typeof i =="string"); console.log(keys) let maps=argv.filter((i)=>typeof i =="object"); return [ Object.entries(styles).filter((i)=>keys.indexOf(i[0])>=0).map((i)=>i[1]).join(" "), _cx(Object.assign({},...maps)) ].join(" "); }; } ////// import styles from "app.less" import classNames from "classnames/bind"; let cx=bindStyles(styles); <div className={cx("app",{"red":true})}> <p className={styles.red}></p> </div> ~~~ # 四、React-Like * * * React 0.14過于老舊,部分特性已被警告使用。部分第三方React-Like框架可以兼容IE8,并且支持React15/16的特性,但redux/react-router還是要使用兼容版本。 ### anujs > [https://github.com/RubyLouvre/anu](https://github.com/RubyLouvre/anu) ~~~ //webpack配置 resolve: { alias: { 'react': 'anujs', 'react-dom': 'anujs', // 若要兼容 IE 請使用以下配置 // 'react': 'anujs/dist/ReactIE', // 'react-dom': 'anujs/dist/ReactIE', // 'redux': 'anujs/lib/ReduxIE',//這主要用于IE6-8,因為官方源碼中的isPlainObject方法性能超差 // 如果引用了 prop-types 或 create-react-class // 需要添加如下別名 'prop-types': 'anujs/lib/ReactPropTypes', 'create-react-class': 'anujs/lib/createClass' //如果你在移動端用到了onTouchTap事件 'react-tap-event-plugin': 'anujs/lib/injectTapEventPlugin', } } ~~~ 使用官方配置進行替換,即可順利編譯和運行,無須額外依賴。 # 五、其它坑 * * * * IE8不支持Websocket,只能使用現代瀏覽器進行日常開發,編譯后再觀察IE8運行效果。 * React編譯樣式比較慢,尤其通過import方式引用樣式時,dev-server經常因爆內存而崩潰。 * 沒有支持IE8的完善組件庫,極有可能仍然離不開JQuery。 [https://www.npmjs.com/package/jquery](https://www.npmjs.com/package/jquery) 封裝JQuery組件時盡量在componentWillUnmount中釋放資源,但并不是所有第三方控件都有資源釋放接口的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看