使用 webpack2 和 NPM Scripts 進行 JavaScript 組件開發
最近 webpack 成為非常流行的打包工具,很多項目都在使用它。在我們進行 JavaScript 獨立組件 開發的時候,如果我們想要使用語言新特性,又想發布的時候產出兼容性好的代碼,那么使用 webpack 就能夠很大程度上幫助我們實現這一目標。
現在讓我們來看看究竟該怎么做吧。
搭建一個簡易環境
首先,第一步是初始化和安裝一些必要的依賴,搭建一個簡易的開發和調試環境:
# 初始化 package.json
npm init -i
# 安裝 http-server
npm install http-server
# 安裝 webpack
npm install webpack webpack-dev-server --save-dev
# 安裝 babel 和 babel 插件,如果不想使用 babel 編譯 ES6+,可以跳過這一步
npm install babel-loader babel-core babel-preset-env --save-dev
有了這個基礎環境之后,我們來配置一份 webpack.config.js
配置 webpack
我們在項目目錄里添加 webpack.config.js
module.exports = function(env = {}){
const webpack = require('webpack'),
path = require('path'),
fs = require('fs'),
packageConf = JSON.parse(fs.readFileSync('package.json', 'utf-8'));
let name = packageConf.name,
version = packageConf.version,
library = name.replace(/^(\w)/, m => m.toUpperCase()),
proxyPort = 8081,
plugins = [],
loaders = [];
if(env.production){
name += `-${version}.min`;
//compress js in production environment
plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_console: false,
}
})
);
}
if(fs.existsSync('./.babelrc')){
//use babel
let babelConf = JSON.parse(fs.readFileSync('.babelrc'));
loaders.push({
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: babelConf
});
}
return {
entry: './lib/app.js',
output: {
filename: `${name}.js`,
path: path.resolve(__dirname, 'dist'),
publicPath: '/static/js/',
library: `${library}`,
libraryTarget: 'umd'
},
plugins: plugins,
module: {
loaders: loaders
},
devServer: {
proxy: {
"*": `http://127.0.0.1:${proxyPort}`,
}
}
};
}
代碼比較長,但不復雜,這里我分別解釋一下各部分的作用:
生產環境和開發環境
首先我們從 package.json 里面取出一些信息,包括模塊名和版本號,我們依賴它們來生成對應的 umd 模塊的 library、輸出的文件名以及版本號。
在這里我們規定在開發環境時輸出 模塊名.js ,在生產環境發布時輸出 模塊名-版本號.min.js 。
在 webpack2 里,我們可以通過 env.production 獲取命令行參數 --production ,從而區別是開發環境還是生產環境。
if(env.production){
name += `-${version}.min`;
//compress js in production environment
plugins.push(
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_console: false,
}
})
);
}
在生產環境中,我們不僅改變輸出的文件名,還配置 UglifyJsPlugin 來壓縮腳本。
使用 babel 編譯 ES6
如果腳本用到 ES6,我們希望用 babel 編譯的話,還需要加載 babel-loader 來進行編譯。我們采用 babel 的默認配置 .babelrc ,在項目目錄里添加 .babelrc:
{
"presets": ["env"],
"plugins": ["transform-runtime"]
}
然后我們在 webpack.config.json 里根據配置來添加 loader:
if(fs.existsSync('./.babelrc')){
//use babel
let babelConf = JSON.parse(fs.readFileSync('.babelrc'));
loaders.push({
test: /\.js$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: babelConf
});
}
配置開發調試的 webpack-dev-server
最后,為了在開發環境里調試,我們還需要配置 webpack-dev-server:
devServer: {
proxy: {
"*": `http://127.0.0.1:${proxyPort}`,
}
}
webpack-dev-server 是一個代理,我們之前安裝了 http-server,我們用 webpack-dev-server 來代理它,所以開發時我們讓 http-server 運行在 8081 端口:
webpack-dev-server --quiet & http-server -p 8081 -c-1
創建 NPM Scripts
配置好了 webpack,創建 NPM Scripts 是個非常簡單的過程:
"scripts": {
[...]
"start": "webpack-dev-server --quiet & http-server -c-1 -p 8081",
"build-release": "webpack --env.production"
},
我們在 package.json 里添加兩個腳本,這樣我們就可以使用 npm start 來啟動開發環境,使用 npm run build-release 來發布到生產環境了。
開始項目開發
接下來我們創建 lib/app.js:
module.exports = require('./demo');
然后創建 lib/demo.js:
module.exports = class Demo{
async test(){
return new Promise((resolve) => {
setTimeout(resolve, 1000)
});
}
}
創建 examples/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
</head>
<body>
<h1>Hello</h1>
<script src="/static/js/demo.js"></script>
<script>
var d = new Demo();
d.test().then(function(){
console.log('test done!');
});
</script>
</body>
</html>
運行 npm start ,訪問 http://localhost:8080/examples/index.html
打開控制臺,1秒后就能看到輸出 test done 。
構建和發布
接下來,我們可以停止開發服務器,運行 npm run build-release 。如果你的 package.json 里的版本號是 1.0.0,那么它將在 dist 目錄下生成 demo-1.1.0.min.js。這是一個 umd 的包,所以你可以在瀏覽器中使用 amd/cmd 庫加載或者直接在 script 標簽中引入和使用。
總結
我們使用 webpack 搭建了一個簡單的組件開發環境,這樣我們可以簡單地開始我們的 JS 組件開發,使用新的語言規范,然后通過 webpack-dev-server 代理 http-server 進行調試,通過 webpack --env.production 進行發布。我們還可以將它們與 NPM Scripts 集成,這樣我們的組件開發就非常方便了。
來自:https://www.h5jun.com/post/using-webpack2-and-npm-scripts.html