1. webpack-打包優化方案
分析打包文件
要優化,先分析。我們先要知道到底是哪裡拖慢我們的打包速度呢?
可以利用 webpack-bundle-analyzer 插件來分析我們打包後生成的文件
修改 webpack.prod.conf.js 文件
simple-progress-webpack-plugin 可以顯示打包百分比
修改 webpack.prod.conf.js 文件
效果如下:
資源與依賴包的控制
通過上面進度可以看到,打包過程中,卡頓在壓縮的地方過長,當項目越來越臃腫的時候,我們要需要對項目靜態資源以及依賴包進行整理,
項目裡面使用 ElementUI 和 Echarts 都是全部引用掛在 Vue.prototype 上,現都改為按需引用。
預處理各種文件時指定匹配目錄後, webpack 解析文件時就不會循環查找其他目錄,加快解析速度。
webpack 執行預處理文件時單線程的,我們可以使用 happypack 來多線程處理文件。
修改 webpack.base.js 文件
babel-plugin-dynamic-import-node 插件是使 import() 替換成 require 編譯
修虛鬧前改 .babelrc 文件
注意 :使用插件 build 後沒有 chunk files 文件。
通差清過 DllPlugin 插件分離出第三方包
使用 add-asset-html-webpack-plugin 動態添加 dll.js 到 html 。
需要注意
項目經過以上優化,打包從彎吵 30 分鍾,到 2 分鍾不到,整體還有優化空間,可以使用其他 cdn 等優化方式。
2. webpack postcss-loader 自動引進postcss.config.js的嗎
CommonJs與AMD在一開始,我們先講一下它和以往我們所用的模塊管理工具有什麼不一樣。在最開始的階段,Js並沒有這些模塊機制,各種Js到處飛,得不到有效妥善的管理。後來前端圈開始制定規范,最耳熟能詳的是CommonJs和AMD。CommonJs是應用在NodeJs,是一種同步的模塊機制。它的寫法大致如下:varfirstMole=require("firstMole");//yourcodemole.export=anotherMoleAMD的應用場景則是瀏覽器,非同步載入的模塊機制。require.js的寫法大致如下:define(['firstMole'],function(mole){//yourcodereturnanotherMole})其實我們單比較寫法,就知道CommonJs是更為優秀的。它是一種同步的寫法,對Human友好,而且代碼也不會繁瑣臃腫。但更重要的原因是,隨著npm成為主流的JavaScript組件發布平台,越來越多的前端項目也依賴於npm上的項目,或者自身就會發布到npm平台。所以我們對如何可以使用npm包中的模塊是我們的一大需求。所以browserify工具就出現了,它支持我們直接使用require()的同步語法去載入npm模塊。當然我們這里不得不說的是,ES2015(ES6)里也有了自己的模塊機制,也就是說ES6的模塊機制是官方規定的,我們通過babel(一種6to5的編譯器)可以使用比較多的新特性了,包括我們提到的模塊機制,而它的寫法大致如下:import{someMole}from"someMole";//yourcodesexportanotherMole;當然上面的寫法只是最基本的,還有其他的不同載入模塊的寫法,可以看一下阮一峰老師的ECMAScript6入門或者babel的相關文檔LearnES2015。功能特性browserify的出現非常棒,但webpack更勝一籌!我們來看看webpack支持哪些功能特性:支持CommonJs和AMD模塊,意思也就是我們基本可以無痛遷移舊項目。支持模塊載入器和插件機制,可對模塊靈活定製。特別是我最愛的babel-loader,有效支持ES6。可以通過配置,打包成多個文件。有效利用瀏覽器的緩存功能提升性能。將樣式文件和圖片等靜態資源也可視為模塊進行打包。配合loader載入器,可以支持sass,less等CSS預處理器。內置有sourcemap,即使打包在一起依舊方便調試。看完上面這些,可以想像它就是一個前端工具,可以讓我們進行各種模塊載入,預處理後,再打包。之前我們對這些的處理是放在grunt或gulp等前端自動化工具中。有了webpack,我們無需藉助自動化工具對模塊進行各種處理,讓我們工具的任務分的更加清晰。
3. webpack如何在頁面中非同步載入js模塊
使用require.ensure作為分割非同步模塊的點
4. webpack非同步載入打包文件名
Webpack非同步載入打梁段包文件的文件名由webpack.config.js中殲賣的output.filename配置氏渣逗項決定,默認情況下,文件名包含了[name]、[hash]和[chunkhash]三個變數,可以根據實際情況自定義文件名。
5. require的用法5種
require的用法5種分類:一、commonjs同步。二、commonjs非同步載入。三、webpack自帶的require.include。四、AMD非同步載入。五、ES6 import。
6. webpack到底是通過什麼方式在瀏覽器上載入的呢
Gulp應該和Grunt比較,他們的區別我就不說了,說說用處吧。Gulp / Grunt 是一種工具,能夠優化前端工作流程。比如自動刷新頁面、combo、壓縮css、js、編譯less等等。簡單來說,就是使用Gulp/Grunt,然後配置你需要的插件,就可以把以前需要手工做的事情讓它幫你做了。
說到 browserify / webpack ,那還要說到 seajs / requirejs 。這四個都是JS模塊化的方案。其中seajs / require 是一種類型,browserify / webpack 是另一種類型。
seajs / require : 是一種在線"編譯" 模塊的方案,相當於在頁面上載入一個 CMD/AMD 解釋器。這樣瀏覽器就認識了 define、exports、mole 這些東西。也就實現了模塊化。
browserify / webpack : 是一個預編譯模塊的方案,相比於上面 ,這個方案更加智能。沒用過browserify,這里以webpack為例。首先,它是預編譯的,不需要在瀏覽器中載入解釋器。另外,你在本地直接寫JS,不管是 AMD / CMD / ES6 風格的模塊化,它都能認識,並且編譯成瀏覽器認識的JS。
這樣就知道,Gulp是一個工具,而webpack等等是模塊化方案。Gulp也可以配置seajs、requirejs甚至webpack的插件。
7. webpack的require和import 有什麼區別
1)將filename對應於entry裡面生成出來的文件名。
{
entry: {
"index": "pages/index.jsx"
},
output: {
filename: "[name].min.js",
chunkFilename: "[name].min.js"
}
}
生成出來的文件名為index.min.js。
2)按需載入(非同步)模塊的時候,使用CommonJS的方式非同步載入模塊,列在entry:
require.ensure(["moles/tips.jsx"], function(require) {
var a = require("moles/tips.jsx");
// ...
}, 'tips');
非同步載入的模塊是要以文件形式載入,生成的文件名是以chunkname配置的,生成出的文件名就是tips.min.js。
wayou.sayName();
wayou.program();
}, 'Programmer');
let animal = new Animal('mmy');
animal.sayName();
3)(require.ensure() API的第三個參數是給這個模塊命名,否則
chunkFilename: "[name].min.js" 中的[name] 是一個自動分配的、可讀性很差的id。
4)按照上述修改才可以單純的指定代碼分塊的輸出目錄而又不影響其它資源的打包目錄。
8. vue組件非同步載入是不是越多越好
vue組件非同步載入不是越多越好。非同步,是相對於同步而言的。我們在使用Vue時,使用到的改閉組件大多為同步組件。在vue實例第一次執行渲染的過程中,已經生成了組件構造器。而非同步組件則是在用到該組件時,非同步通過請求去拉取對應組件的js(這里需要和webpack的import相結合)。當核絕裂對應的js載入完成後,獲取到非同步組件的配置項,從而創建組件構造器。再通過forceRender,強宏稿制依賴它的vm實例重新觸發渲染函數。
9. 如何用 webpack fetch 非同步引用 json
他像 Browserify, 但是將你的應用打包為多個文件. 如果你的單頁面應用有多個頁面, 那麼用戶只從下載對應頁面的代碼. 當他么訪問到另一個頁面, 他們不需要重新下載通用的代碼.
他在很多地方能替代 Grunt 跟 Gulp 因為他能夠編譯打包 CSS, 做 CSS 預處理, 編譯 JS 方言, 打包圖片, 還有其他一些.
它支持 AMD 跟 CommonJS, 以及其他一些模塊系統, (Angular, ES6). 如果你不知道用什麼, 就用 CommonJS.
2. Webpack 給 Browserify 的同學用
對應地:
browserify main.js > bundle.js
webpack main.js bundle.js
Webpack 比 Browserify 更強大, 你一般會用 webpack.config.js 來組織各個過程:
// webpack.config.js
mole.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
這僅僅是 JavaScript, 可以隨意添加要運行的代碼.
3. 怎樣啟動 webpack
切換到有 webpack.config.js 的目錄然後運行:
webpack 來執行一次開發的編譯
webpack -p for building once for proction (minification)
webpack -p 來針對發布環境編譯(壓縮代碼)
webpack --watch 來進行開發過程持續的增量編譯(飛快地!)
webpack -d 來生成 SourceMaps
4. JavaScript 方言
Webpack 對應 Browsserify transform 和 RequireJS 插件的工具稱為 loader. 下邊是 Webpack 載入 CoffeeScript 和 Facebook JSX-ES6 的配置(你需要 npm install jsx-loader coffee-loader):
// webpack.config.js
mole.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
mole: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{ test: /\.js$/, loader: 'jsx-loader?harmony' } // loaders 可以接受 querystring 格式的參數
]
}
};
要開啟後綴名的自動補全, 你需要設置 resolve.extensions 參數指明那些文件 Webpack 是要搜索的:
// webpack.config.js
mole.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
mole: {
loaders: [
{ test: /\.coffee$/, loader: 'coffee-loader' },
{ test: /\.js$/, loader: 'jsx-loader?harmony' }
]
},
resolve: {
// 現在可以寫 require('file') 代替 require('file.coffee')
extensions: ['', '.js', '.json', '.coffee']
}
};
5. 樣式表和圖片
首先更新你的代碼用 require() 載入靜態資源(就像在 Node 里使用 require()):
require('./bootstrap.css');
require('./myapp.less');
var img = document.createElement('img');
img.src = require('./glyph.png');
當你引用 CSS(或者 LESS 吧), Webpack 會將 CSS 內聯到 JavaScript 包當中, require() 會在頁面當中插入一個 `<style>標簽. 當你引入圖片, Webpack 在包當中插入對應圖片的 URL, 這個 URL 是由require()` 返回的.
你需要配置 Webpack(添加 loader):
// webpack.config.js
mole.exports = {
entry: './main.js',
output: {
path: './build', // 圖片和 JS 會到這里來
publicPath: 'http://mycdn.com/', // 這個用來成成比如圖片的 URL
filename: 'bundle.js'
},
mole: {
loaders: [
{ test: /\.less$/, loader: 'style-loader!css-loader!less-loader' }, // 用 ! 來連接多個人 loader
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'} // 內聯 base64 URLs, 限定 <=8k 的圖片, 其他的用 URL
]
}
};
6. 功能開關
有些代碼我們只想在開發環境使用(比如 log), 或者 dogfooging 的伺服器里邊(比如內部員工正在測試的功能). 在你的代碼中, 引用全局變數吧:
if (__DEV__) {
console.warn('Extra logging');
}
// ...
if (__PRERELEASE__) {
showSecretFeature();
}
然後配置 Webpack 當中的對應全局變數:
// webpack.config.js
// definePlugin 接收字元串插入到代碼當中, 所以你需要的話可以寫上 JS 的字元串
var definePlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true')),
__PRERELEASE__: JSON.stringify(JSON.parse(process.env.BUILD_PRERELEASE || 'false'))
});
mole.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [definePlugin]
};
然後你在控制台里用 BUILD_DEV=1 BUILD_PRERELEASE=1 webpack 編譯. 注意一下因為 webpack -p 會執行 uglify dead-code elimination, 任何這種代碼都會被剔除, 所以你不用擔心秘密功能泄漏.
7. 多個進入點(entrypoints)
比如你用 profile 頁面跟 feed 頁面. 當用戶訪問 profile, 你不想讓他們下載 feed 頁面的代碼. 因此你創建多個包: 每個頁面一個 "main mole":
// webpack.config.js
mole.exports = {
entry: {
Profile: './profile.js',
Feed: './feed.js'
},
output: {
path: 'build',
filename: '[name].js' // 模版基於上邊 entry 的 key
}
};
針對 profile, 在頁面當中插入 <script src="build/Profile.js"></script>. feed 頁面也是一樣.
8. 優化共用代碼
feed 頁面跟 profile 頁面共用不要代碼(比如 React 還有通用的樣式和 component). Webpack 可以分析出來他們有多少共用模塊, 然後生成一個共享的包用於代碼的緩存.
// webpack.config.js
var webpack = require('webpack');
var commonsPlugin =
new webpack.optimize.CommonsChunkPlugin('common.js');
mole.exports = {
entry: {
Profile: './profile.js',
Feed: './feed.js'
},
output: {
path: 'build',
filename: '[name].js'
},
plugins: [commonsPlugin]
};
在上一個步驟的 script 標簽前面加上 <script src="build/common.js"></script> 你就能得到廉價的緩存了.
9. 非同步載入
CommonJS 是同步的, 但是 Webpack 提供了非同步指定依賴的方案. 這對於客戶端的路由很有用, 你想要在每個頁面都有路由, 但你又不像在真的用到功能之前就下載某個功能的代碼.
聲明你想要非同步載入的那個"分界點". 比如:
if (window.location.pathname === '/feed') {
showLoadingState();
require.ensure([], function() { // 語法奇葩, 但是有用
hideLoadingState();
require('./feed').show(); // 函數調用後, 模塊保證在同步請求下可用
});
} else if (window.location.pathname === '/profile') {
showLoadingState();
require.ensure([], function() {
hideLoadingState();
require('./profile').show();
});
}
Webpack 會完成其餘的工作, 生成額外的 chunk 文件幫你載入好.
Webpack 在 HTML script 標簽中載入他們時會假設這些文件是怎你的根路徑下. 你可以用 output.publicPath 來配置.
// webpack.config.js
output: {
path: "/home/proj/public/assets", // path 指向 Webpack 編譯能的資源位置
publicPath: "/assets/" // 引用你的文件時考慮使用的地址
10. js非同步載入的callback()方法是怎麼回事
上面的來callback()方法是參數傳入的源,當然需要你在外部定義一個函數。
回調函數,就是當載入完成後,可以進行下一步操作的函數。
舉個簡單的例子:
登陸操作,當輸入用戶名和密碼進行登陸後,發送一個非同步請求至服務端,來驗證是否為合法用戶。
假如服務端的驗證方法,返回一個true|false的布爾值。
客戶端腳本中在得到服務端的響應後,就可以進入回調函數。
那麼在回調函數中,可以根據這個返回值,進行相應的操作。比如,true的話,跳轉到主頁面;false的話,重新定位到登陸頁面。
回調函數在ajax中還是很有用的。