前端工具的安裝


前端工具安裝簡述

前言

  雖然一直有寫前端,而且水平自認上升很快,但是仍然沒有玩過模塊化開發。

  對於前端的這些工具也沒有接觸過,平時一般都是vs和vs code就搞定了,為了搞一搞模塊化開發,准備來玩一下這些前端工具。

  所以寫寫這些前端工具的安裝步驟,記錄一下以后忘了也能用,如果能幫到別人就更好了。

1、NPM和Node.js的安裝

  安裝node.js后,自動就安裝了npm,所以這里兩者寫到一起了。

  nodejs的下載地址:

  https://nodejs.org/en/download/

  這種東西給個下載地址就好了,根據自己電腦類型安裝,做程序員的也沒有電腦小白,下一步就不說了。

  npm下載源的配置

  npm在這里被我理解為一個下載工具,而下載的地址為https://www.npmjs.com 。

  只不過在國內訪問不穩定,因此建議使用國內鏡向站點https://npm.taobao.org 。

  在cmd.exe中,運行以下命令即可:

npm --registry https://registry.npm.taobao.org info underscore

  或者找到Nodejs安裝文件夾中的npmrc文件,在該文件中加入

registry = https://registry.npm.taobao.org

2、gulp的安裝

  gulp用來優化前端工作流程。

  全局安裝gulp:  

npm install gulp -g

  輸入gulp -v可以查看到相應版本

  使用到項目中:

  以下是我用vs code自己建的一個項目:

  

  命令行cd到自己建的項目文件夾,然后npm init即可生成自己的package.json,這是自己項目的每個項目的一個描述文件,定義了這個項目所需要的各種模塊,以及項目的配置信息(比如名稱、版本、許可證等元數據)。

  將gulp安裝到項目中

npm install gulp --save-dev

  安裝后:

  

  此時項目中多了node_modules這個文件夾,同時package.json中自動寫入了devDependencies字段,並在該字段下填充了gulp模塊名。

  

  接下來安裝上面gulp中可用的一堆插件

npm install --save-dev gulp-uglify gulp-concat gulp-imagemin gulp-htmlmin gulp-clean-css gulp-rev-append gulp-autoprefixer

  安裝后:

  

 

  gulp-uglify為壓縮js文件,gulp-concat為合並打包文件,gulp-imagemin為壓縮圖片,gulp-htmlmin為壓縮html,gulp-clean-css壓縮css文件,gulp-rev-append為添加版本號。

  實際上.NET MVC的bundle繼承了上面這些功能,所以用.net進行開發貌似完全用不到,不過想來別的語言也許應該還是需要的。

  而gulp-autoprefixer是根據設置瀏覽器版本自動處理瀏覽器前綴,gulp-less插件將less文件編譯成css,當有less文件發生改變自動編譯less,並保證less語法錯誤或出現異常時能正常工作並提示錯誤信息。

  肯定還是有一些別的功能的插件,這只是我暫時了解到的幾個,如果有其它好用的也希望有大神能留言告訴我一下。

  編寫gulpfile.js文件

  如果要用這些插件,那么還要在根目錄下加一個gulpfile.js配置文件,以下為我自己的測試項目:

  

  根據測試項目寫的配置文件:

/*引入gulp及相關插件 require('node_modules里對應模塊')*/
var gulp = require('gulp');
var minifyCss = require("gulp-clean-css"),
    uglify = require('gulp-uglify'),
    concat = require('gulp-concat'),
    imagemin = require('gulp-imagemin'),
    htmlmin = require('gulp-htmlmin'),
    rev = require('gulp-rev-append'),
    autoprefixer = require('gulp-autoprefixer'),
    less = require('gulp-less');
//壓縮html,並給頁面的引用添加版本號,清除頁面引用緩存
gulp.task('minifyHtml', function() {
    var options = {
        removeComments: true, //清除HTML注釋
        collapseWhitespace: true, //壓縮HTML
        collapseBooleanAttributes: true, //省略布爾屬性的值 <input checked="true"/> ==> <input />
        removeEmptyAttributes: true, //刪除所有空格作屬性值 <input id="" /> ==> <input />
        removeScriptTypeAttributes: true, //刪除<script>的type="text/javascript"
        removeStyleLinkTypeAttributes: true, //刪除<style>和<link>的type="text/css"
        minifyJS: true, //壓縮頁面JS
        minifyCSS: true //壓縮頁面CSS
    };
    gulp.src('examples/*.html')
        .pipe(htmlmin(options))
        .pipe(rev())
        .pipe(gulp.dest('dist/html'));
});
//壓縮圖片
gulp.task('minify-img', function() {
    gulp.src('src/img/*.{png,jpg,gif,ico}')
        .pipe(imagemin())
        .pipe(gulp.dest('dist/img/'));
});
//編譯less
gulp.task('handleLess', function() {
    gulp.src('src/less/*.less')
        .pipe(less())
        .pipe(gulp.dest('src/css'));
});
//設置瀏覽器版本自動處理瀏覽器前綴,並壓縮css
gulp.task('minify-css', function() {
    gulp.src('src/css/*.css')
        .pipe(autoprefixer({
            browsers: ['last 2 versions', 'Android >= 4.0'],
            cascade: true, //是否美化屬性值 默認:true 像這樣:
            //-webkit-transform: rotate(45deg);
            //        transform: rotate(45deg);
            remove: true //是否去掉不必要的前綴 默認:true 
        }))
        .pipe(minifyCss())
        .pipe(gulp.dest('dist/css/'));
});
//打包並壓縮js
gulp.task('minify-script', function() {
    gulp.src('src/js/*.js')
        .pipe(concat('helloworld.js')) //打包
        .pipe(uglify()) //壓縮
        .pipe(gulp.dest('dist/js/'));
});
gulp.task('default', ['minifyHtml', 'minify-img', 'handleLess', 'minify-css', 'minify-script']);

   運行gulp完成前端構建

   根據上面的配置我們可以在命令行輸入 :

gulp minify-script

   這就只打包壓縮JS文件,也可以輸入:

gulp minify-script

   這樣就完成我們所有的構建工作。

  進一步的學習可以轉到:http://www.gulpjs.com.cn/

3、webpack的安裝

  webpack是一個前端模塊化方案,只不過是本地的,而類似requireJs和sea.js是在線模塊化方案。

  有了上面安裝gulp的經驗webpack就簡單多了。

  安裝webpack :

npm install webpack -g

  接下來增加package.json配置文件,也就是

npm init

  只不過我們前面配置了,那么直接下一步:

npm install webpack --save-dev

  同樣這個webpack也會加到node_modules文件夾中。

那么來一段簡單的前端示例,使用webpack來實現前端模塊化,我有兩個文件:

hello.js

window.resize = function() {
    console.info("我resize了!");
}

helloApp.js

var hello = require('./hello.js');
console.log(hello);

雖然不清楚語法,但是大概也能明白,helloApp.js引用了hello.js。

運行

 webpack src/js/helloApp.js dist/js/helloApp.Main.js

然后生成的helloApp.Main.js是下面這個樣子:

/******/ (function(modules) { // webpackBootstrap
/******/     // The module cache
/******/     var installedModules = {};
/******/
/******/     // The require function
/******/     function __webpack_require__(moduleId) {
/******/
/******/         // Check if module is in cache
/******/         if(installedModules[moduleId]) {
/******/             return installedModules[moduleId].exports;
/******/         }
/******/         // Create a new module (and put it into the cache)
/******/         var module = installedModules[moduleId] = {
/******/             i: moduleId,
/******/             l: false,
/******/             exports: {}
/******/         };
/******/
/******/         // Execute the module function
/******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/         // Flag the module as loaded
/******/         module.l = true;
/******/
/******/         // Return the exports of the module
/******/         return module.exports;
/******/     }
/******/
/******/
/******/     // expose the modules object (__webpack_modules__)
/******/     __webpack_require__.m = modules;
/******/
/******/     // expose the module cache
/******/     __webpack_require__.c = installedModules;
/******/
/******/     // identity function for calling harmony imports with the correct context
/******/     __webpack_require__.i = function(value) { return value; };
/******/
/******/     // define getter function for harmony exports
/******/     __webpack_require__.d = function(exports, name, getter) {
/******/         if(!__webpack_require__.o(exports, name)) {
/******/             Object.defineProperty(exports, name, {
/******/                 configurable: false,
/******/                 enumerable: true,
/******/                 get: getter
/******/             });
/******/         }
/******/     };
/******/
/******/     // getDefaultExport function for compatibility with non-harmony modules
/******/     __webpack_require__.n = function(module) {
/******/         var getter = module && module.__esModule ?
/******/             function getDefault() { return module['default']; } :
/******/             function getModuleExports() { return module; };
/******/         __webpack_require__.d(getter, 'a', getter);
/******/         return getter;
/******/     };
/******/
/******/     // Object.prototype.hasOwnProperty.call
/******/     __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/     // __webpack_public_path__
/******/     __webpack_require__.p = "";
/******/
/******/     // Load entry module and return exports
/******/     return __webpack_require__(__webpack_require__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {

window.resize = function() {
    console.info("我resize了!");
}

/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {

var hello = __webpack_require__(0);
console.log(hello);

/***/ })
/******/ ]);

一大段代碼看着就很捉急,不過實際上看看也不過就是個立即執行函數,我刪減了一些代碼,並進行了一些格式化,以下是我的代碼:

(function(modules) { 
    //將我們兩個文件中的代碼作為一個函數對象傳進這里
    //然后進行某些處理
})
(
    [ 
        (
            function(module, exports) {
                //仔細對照,這是我們被引用的hello.js的代碼
                window.resize = function() {
                    console.info("我resize了!");
                }
            }
        ),
        (
            function(module, exports, __webpack_require__) {
                //仔細對照,這是我們的helloApp.js的代碼,
                //只不過require被換位了__webpack_require__
                //而里面的路徑'./hello.js'被換位了0,哈,簡單猜想一下,這個0就是我們hello.js的代碼所在的函數對象,在傳進去的moudles數組中所在的索引
                var hello = __webpack_require__(0);
                console.log(hello);
            }
        ) 
    ]
);

然后我們加入部分被刪掉的代碼:

(function(modules) { 
            // The module cache
/******/     var installedModules = {};
/******/     // The require function
            //(2)第二步看第一步調用的這個函數,果然1就是moduleId
/******/     function __webpack_require__(moduleId) {
/******/
/******/         //  Check if module is in cache
                //  查看模塊緩存中有不有moduleId為1的,有就直接返回installedModules[moduleId].exports
                //  讀到這里只知道起到個緩存的作用,先不管這個是什么鬼,下一步
/******/         if(installedModules[moduleId]) {
/******/             return installedModules[moduleId].exports;
/******/         }
/******/         // Create a new module (and put it into the cache)
                // 走到這里,肯定表示沒緩存嘛,於是創建下面這個對象
                // 這個對象的i為入口模塊索引,
                // l是false,不知道什么鬼不管,
                // exports就是輸出對象嘛,同時將這個對象的引用交給了installedModules[moduleId]和module
                // 也就是說這個對象我們緩存了
/******/         var module = installedModules[moduleId] = {
/******/             i: moduleId,
/******/             l: false,
/******/             exports: {}
/******/         };
/******/
/******/         // Execute the module function
                // 來到了有趣的地方,modules是我們傳進來的模塊數組,modules[moduleId]就是我們的入口函數,也就是下面這個:
                //  (
                //        function(module, exports, __webpack_require__) {
                //            hello = __webpack_require__(0);
                //            console.log(hello);
                //        }
                //    ) 
                // 那么運行下面代碼的大致效果就是:
                //  var entryModule=function(module, exports, __webpack_require__) {
                //    hello = __webpack_require__(0);
                //    console.log(hello);
                //  };
                //  entryModule(module,module.exports,__webpack_require__);
                //  這段代碼的就厲害了,又執行了__webpack_require__這個函數,不過此時的參數為0,也就是我們那個被引用的js的代碼的函數對象的索引
/******/         modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/         // Flag the module as loaded
                // 此時我們了解到l的作用表示這個模塊是否被加載
/******/         module.l = true;
/******/
/******/         // Return the exports of the module
                // 然后返回 module.exports,
                // 如果此時是hello.js的代碼運行完,那么此時就會將hello.js中給形參exports的部分返回給hello那個變量
                // 此時我就明白了,webpack在不同的js之間如何建立依賴關系
                // 讓被引用的部分只返回希望返回的部門,放到exports中,供引用的js調用
/******/         return module.exports;
/******/     }
/******/
/******/     // Load entry module and return exports
            // (1)第一步,看上面自帶的注釋,表示:這是載入入口模塊,並且返回輸出
            //  這個入口模塊什么的,給了個s什么的,然后給了它個1,這里的s暫時看着沒什么用啊
            // 那么就看成__webpack_require__(1)就好了
            // 這個1的話我們猜測就是傳進來的module數組中那個引用其他js的helloApp.js的代碼的函數對象的索引
/******/     return __webpack_require__(__webpack_require__.s = 1);
})
(
    [ 
        (
            function(module, exports) {
                //仔細對照,這是我們被引用的hello.js的代碼
                window.resize = function() {
                    console.info("我resize了!");
                }
            }
        ),
        (
            function(module, exports, __webpack_require__) {
                //仔細對照,這是我們的helloApp.js的代碼,
                //只不過require被換位了__webpack_require__
                //而里面的路徑'./hello.js'被換位了0,哈,簡單猜想一下,這個0就是我們hello.js的代碼所在的函數對象,在傳進去的moudles數組中所在的索引
                hello = __webpack_require__(0);
                console.log(hello);
            }
        ) 
    ]
);

OK,到了這里,我對webpack的大致功能就有了一個了解~~~~~。

這不就跟我們在.net或者java中的using或import一樣嘛,而上面這個這個東西就是我們的Main函數,果然,沒什么高大上的,其實就是這么簡單。

接下來就去了解一下webpack的具體配置,首先新建一個webpack.config.js文件,然后讓打包簡單化:

module.exports = {
    entry: './src/app.js',
    output: {
        path: './dist',
        filename: 'app.bundle.js'
    }
};

然后直接運行webpack命令即可,就相當於自動去找webpack.config.js文件,然后根據文件中的入口app.js去生成app.bundle.js。

到這里意思就很明白了,webpack實際上就是一個類似Seajs、RequireJS一樣的東西。

接下來的工作貌似就是去查webpack的如何去配置什么的了,這種細枝末節的這里就不講了。

貌似這是一個安裝的帖子 ~~~

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM