gulp+webpack多頁應用開發,webpack僅處理打包js

項目背景:一個綜合網站,開發模式爲後端嵌套數據,前端開發靜態頁面和部分組件。css

問題:gulp任務處理自動刷新、sass編譯等都是極好的。可是對於js的處理並非很好,尤爲是項目須要開發組件時候,如評論組件,須要有模版、css、js[各個模塊]。這時候選擇用gulp感受並不合適,固然能夠選擇require.js or seajs等AMD/CMD規範來開發,可是想一想項目中的組件應該是獨立於項目以外的,不依賴於任何第三方js,所以選擇去折騰webpack+gulp來搞。幾番折騰、百度以後,配置以下:html

package.js前端

{
  "name": "work",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "autoprefixer": "^6.3.6",
    "autoprefixer-core": "^6.0.1",
    "babel-core": "^6.24.1",
    "babel-loader": "^7.0.0",
    "babel-preset-es2015": "^6.24.1",
    "browser-sync": "^2.13.0",
    "cssgrace": "^3.0.0",
    "cssnext": "^1.8.4",
    "del": "^2.2.1",
    "extract-text-webpack-plugin": "^2.1.0",
    "fs": "^0.0.2",
    "gulp": "^3.9.1",
    "gulp-babel": "^6.1.2",
    "gulp-concat": "^2.6.0",
    "gulp-htmlmin": "^2.0.0",
    "gulp-imagemin": "^3.0.1",
    "gulp-jshint": "^2.0.1",
    "gulp-less": "^3.1.0",
    "gulp-livereload": "^3.8.1",
    "gulp-minify-css": "^1.2.4",
    "gulp-notify": "^2.2.0",
    "gulp-plumber": "^1.1.0",
    "gulp-postcss": "^6.1.1",
    "gulp-rename": "^1.2.2",
    "gulp-sass": "^2.3.2",
    "gulp-uglify": "^1.5.3",
    "gulp-util": "^3.0.7",
    "gulp-watch": "^4.3.8",
    "gulp-webpack": "^1.5.0",
    "imagemin-jpegtran": "^5.0.2",
    "imagemin-pngcrush": "^5.0.0",
    "jshint": "^2.9.2",
    "json-loader": "^0.5.4",
    "node-sass": "^4.5.2",
    "path": "^0.12.7",
    "run-sequence": "^1.2.1",
    "through2": "^2.0.1",
    "webpack": "^2.4.1"
  }
}
View Code

package中有部分插件並未使用,自行選擇安裝。node

 

gulp配置[gulpfile.js],關於gulp使用請參考這篇文章webpack

  1 var gulp = require("gulp")
  2             , gutil = require("gulp-util")
  3 
  4             , del = require("del")
  5             , sass = require("gulp-sass")
  6             , uglify = require('gulp-uglify')
  7             , rename = require("gulp-rename")
  8 
  9             , browserSync = require("browser-sync").create()
 10             , reload = browserSync.reload
 11 
 12             , sequence = require("run-sequence")
 13             , plumber = require("gulp-plumber")
 14             , watch = require("gulp-watch")
 15 
 16             , through2 = require("through2")
 17             , path = require("path")
 18             , fs = require("fs")
 19             , minifycss = require('gulp-minify-css')
 20             , postcss = require('gulp-postcss')
 21             , autoprefixer = require('autoprefixer') // Autoprefixer 爲CSS補全瀏覽器前綴
 22             , cssnext  = require('cssnext') // CSSNext 用下一代CSS書寫方式兼容如今瀏覽器
 23             , cssgrace  = require('cssgrace') // CSS Grace 讓CSS兼容舊版IE
 24             , webpack = require('webpack');
 25 
 26 // #############################################
 27 // # init params
 28 // 收集參數
 29 var cwd = process.cwd();
 30 var cmdargs = process.argv.slice(2);
 31 var cmdname = cmdargs.shift();
 32 var cmdopts = {};
 33 var srcpath = "./src";
 34 var distpath = "./dist";
 35 
 36 while (cmdargs.length) {
 37     var key = cmdargs.shift().slice(2);
 38     var val = cmdargs.shift();
 39     cmdopts[key] = key === "src" || key === "dist" ? normalizePath(val) : val;
 40 }
 41 
 42 // 參數配置
 43 var release = cmdname === "release";
 44 var reloadTimer = null;
 45 var devport = 5678;
 46 var paths = {
 47     src: path.join(__dirname, srcpath),
 48     dist: path.join(__dirname, distpath)
 49 }
 50 
 51 function normalizePath(url) {
 52     if (url.charAt(0) === "/" || url.indexOf(":") > -1) {
 53         return path.normalize(url);
 54     }
 55     return path.normalize(path.join(cwd, url));
 56 }
 57 
 58 function setOptions(cmd, cmdopts) {
 59     if (cmd === "start") {
 60         paths.src = cmdopts.src ? path.join(cmdopts.src, srcpath) : paths.src;
 61     } else if (cmd === "release") {
 62         paths.src = cmdopts.src ? path.join(cmdopts.src, srcpath) : paths.src;
 63         paths.dist = cmdopts.dist ? cmdopts.dist : path.normalize(paths.src + "/../" + distpath);
 64     }
 65 }
 66 
 67 function showUsage() {
 68     console.log("Usage:\n");
 69     console.log("     gulp                   顯示幫助");
 70     console.log("     gulp help              顯示幫助");
 71     console.log("     gulp start --src src   在--src目錄下自動化開發調試環境");
 72     console.log("     gulp release --src src --dist dist 構建--src線上版本到--dist目錄\n");
 73     console.log("     gulp start --src src --proxy localhost   使用gulp代理localhost請求,而且實時監聽src文件修改");
 74 }
 75 
 76 // #############################################
 77 // # default tasks
 78 
 79 // # clean path
 80 gulp.task("clean:dist", function() {
 81     return del([paths.dist], {
 82         force: true
 83     });
 84 });
 85 
 86 // # 編譯css
 87 gulp.task("sass", function() {
 88     var base = paths.src;
 89     var dest = base;
 90     var processors = [
 91         autoprefixer({
 92             browsers: ['last 3 version', '> 5%', 'Android >= 4.0', 'iOS >= 7'],
 93             cascade: false, //是否美化屬性值 默認:true 像這樣:
 94             remove: true //是否去掉沒必要要的前綴 默認:true 
 95         }),
 96         // cssnext(),
 97         // cssgrace
 98     ];
 99     return gulp.src(base + "/**/*.scss", {
100             base: base
101         })
102         .pipe(plumber())
103         .pipe(sass({
104                 precision: 2,
105                 outputStyle: release ? "compressed" : "expanded"
106                     //sourceComments: release ? false : true
107             })
108             .on("error", sass.logError))
109         .pipe(postcss(processors))
110         .pipe(gulp.dest(dest));
111 });
112 // 編譯單個css
113 function parseSingleFile(file) {
114     var base = paths.src;
115     var dest = base;
116     var processors = [
117         autoprefixer({
118             browsers: ['last 3 version', '> 5%', 'Android >= 4.0', 'iOS >= 7'],
119             cascade: false, //是否美化屬性值 默認:true 像這樣:
120             remove: true //是否去掉沒必要要的前綴 默認:true 
121         }),
122         // cssnext(),
123         // cssgrace
124     ];
125     return gulp.src(file, {
126             base: base
127         })
128         .pipe(plumber())
129         .pipe(sass({
130                 precision: 2,
131                 outputStyle: release ? "compressed" : "expanded"
132                     //sourceComments: release ? false : true
133             })
134             .on("error", sass.logError))
135         .pipe(postcss(processors))
136         .pipe(gulp.dest(dest));
137 }
138 
139 
140 // # 壓縮js
141 gulp.task("uglify", function() {
142     var base = paths.src;
143     var dest = paths.dist;
144     return gulp.src([
145             base + "/**/*.js",
146             "!" + base +"/**/*-component/**",
147             "!" + base + "/**/*min.js" // 排除壓縮min.js文件
148         ], {
149             base: base
150         })
151         .pipe(plumber())
152         .pipe(uglify())
153         .pipe(gulp.dest(dest));
154 });
155 
156 // # 調用webpack處理component
157 function parseComponentToWebpack(path){
158     var webpackConfig = require('./webpack.config.js');
159     // 靈活處理output位置,將js文件生成在component同級目錄
160     // 將**/*-component/xx.js路徑替換爲**
161     // var outputPath = path.replace(/\/[^\/]+\/[^\/]+$/,'');
162     var outputPath = path.replace(/\/([^\/]+)-component\/[^\/]+$/,'');
163     var filename = RegExp.$1;
164     webpackConfig.entry = {};
165     webpackConfig.entry[filename] = path+'/../index.js';
166     // windows上webpack不認識D:/xxx路徑,替換爲D:\\xxx路徑
167     outputPath = outputPath.replace('/','\\\\');
168     webpackConfig.output.path = outputPath;
169     return webpack(webpackConfig, function(err, stats) {
170         console.log(stats.toString());
171     });
172 }
173 
174 
175 // # 壓縮css
176 gulp.task("mincss", function() {
177     var base = paths.src;
178     var dest = paths.dist;
179     gulp.src(dest + '/**/*.css')
180         .pipe(minifycss())
181         .on('error', function(e) {
182             console.log(e)
183         })
184         .pipe(gulp.dest(dest));
185 });
186 
187 // # 複製靜態資源
188 gulp.task("copy:dist", function() {
189     var base = paths.src;
190     var dest = paths.dist;
191     // 複製min.js文件
192     gulp.src([
193             base + "/**/*min.js"
194         ], {
195             base: base
196         })
197         .pipe(gulp.dest(dest));
198     return gulp.src([
199             base + "/**/*",
200             "!" + base +"/**/*-component",
201             "!" + base +"/**/*-component/**",
202             "!" + base + "/**/*.js",
203             "!" + base + "/**/*.scss"
204         ], {
205             base: base
206         })
207         .pipe(gulp.dest(dest));
208 });
209 
210 
211 // # serv & watch
212 gulp.task("server", function() {
213     // start server
214     browserSync.init({
215         ui: false,
216         notify: false,
217         port: devport,
218         // 設置代理請求
219         proxy: cmdopts.proxy,
220         server: !cmdopts.proxy ? {
221             baseDir: paths.src
222         } : false
223     });
224 
225     // # watch src資源, 調用相關任務預處理
226     // # 刷新瀏覽器
227     // # 限制瀏覽器刷新頻率
228     watch(paths.src + "/**/*", function(obj) {
229         var url = obj.path.replace(/\\/g, "/");
230         var absurl = url;
231         url = path.relative(paths.src, url).replace(/\\/g, "/");
232         console.log("[KS] " + absurl);
233 
234         // skip scss & css
235         if (!/\.scss$/.test(url) && !/\.css$/.test(url)) {
236             if (/.+-component\/.+\.js$/.test(url)) {
237                 // 評論組件,調用webpack
238                 console.log("[webpack] "+absurl);
239                 parseComponentToWebpack(absurl);
240                 return;
241             }
242             if (reloadTimer) {
243                 clearTimeout(reloadTimer);
244             }
245             reloadTimer = setTimeout(reload, 1000);
246         }else if(/\.scss$/.test(url)){
247             // sass任務
248             parseSingleFile(absurl)
249             // 無刷新加載css
250             .pipe(reload({
251                 stream: true
252             }));
253             // sequence("sass");
254         }
255     });
256 });
257 
258 
259 // #############################################
260 // # public task
261 
262 gulp.task("default", showUsage);
263 gulp.task("help", showUsage);
264 
265 gulp.task("start", function(cb) {
266     release = false;
267     setOptions("start", cmdopts);
268     sequence("sass", "server", cb);
269 });
270 
271 gulp.task("release", function(cb) {
272     release = true;
273     setOptions("release", cmdopts);
274     sequence("clean:dist", "copy:dist", ["mincss", "uglify"], cb);
275 });

 

 

webpack配置(webpack.config.js),webpack配置參考es6

 1 var webpack = require('webpack');
 2 
 3 module.exports = {
 4     // devtool: 'eval-source-map',
 5     devtool: false,
 6     entry: {
 7         "component-comment": __dirname + "/src/assets/comment/component/index.js"
 8     },
 9     output: {
10         // path: __dirname + "/src/assets/comment",
11         path: __dirname + "/dist/component",
12         filename: "[name].js"
13     },
14 
15     module: {
16         rules: [{
17                 test: /\.json$/,
18                 loader: "json-loader"
19             },
20             {
21                 test: /\.js$/,
22                 exclude: /node_modules/,
23                 loader: 'babel-loader', //在webpack的module部分的loaders裏進行配置便可
24                 /*query: {
25                     presets: ['es2015']
26                 }*/
27                 query: {
28                     presets: [
29                         ['es2015', {
30                             'modules': false //babel不編譯es6的模塊加載,讓webpack支持Tree-shaking
31                         }]
32                     ]
33                 }
34             },
35         ]
36     },
37 
38 }

 

以上配置webpack將單獨處理component目錄中的js文件,並在component同級目錄生成文件夾相同名字的js文件(如:'./component-comment-component/' 文件夾對應的js文件爲 './component-comment.js')。web

如下是個人文件結構ajax

 1 src
 2     app
 3         *.html                                    //html目錄
 4     assets                                        //靜態資源目錄
 5         component-comment-component               //評論組件
 6             images                                //評論組件所用圖片
 7             component                             //組件模塊
 8                 common.js                         //公用方法,如ajax、jsonp、extend等方法
 9                 defaultConfig.js                  //默認配置
10                 emoticon.js                       //表情模塊,如獲取服務端表情資源,渲染表情等
11                 index.js                          //主模塊,如獲取評論、發表評論、點贊、回覆、舉報等
12                 selector.js                       //選擇器方法,模擬jQuery封裝
13                 template.js                       //模版
14             component-comment.js              //webpack編譯component目錄的js
15             component-comment.scss            //評論樣式表
16             component-comment.css             //編譯的sass文件
17         css                                        //項目其餘sass|css資源
18         images                                     //項目圖片文件
19         js                                         //項目的其餘js

 

以上只是一個簡單的使用案例,針對不一樣結構須要做出不一樣調整。json

相關文章
相關標籤/搜索