gulpを捨てるjs+require.js,webpackを用いてマルチページwebプロジェクトを構成する

6956 ワード

下のくだらない話を見たくないなら、直接ここを見てもいいです.
前言
この2週間、会社の先端基礎工事の建設を担当します.主に2つのシナリオを作成しました.1つはvueベースの単一ページアプリケーションで、もう1つはマルチページアプリケーションです.vue単ページについては問題ありませんが、直接vue-cliでプロジェクトを生成し、vueファミリーバケツやツール関数をタップして、ディレクトリ構造などを規範化する基本はokです.
面倒なのはgulp+requireを使うことです.jsという案.これは私が会社に来る前から存在していましたが、私が来たばかりの頃はgrunt+requireを使っていました.js+jQuery(zepto)+sass、そして私がこの初めてプロジェクトを書いたとき、gruntの緩慢さに耐えられずgulpに変えました.今回はこの案について私ももともと少し変えたいだけです.この案は使ってもいいので、ES 6を追加してrequire.jsは乾いて、それから他の小さな問題の修復があればいいです.
そしてgulpタスクにbabel処理ES 6を加えることを考え始めた.そして実行すると、ES 6のmoduleを使用してimportexportでモジュール化された開発が行われると、babelトランスコードによりimportexportがCMD仕様に適合したrequireexportsなどに変換されるが、ブラウザはまだ走れず、bowserify、webpack、rollupなどのコードを再構築します.これは面倒ですから、webpackを使って一歩進んだほうがいいです.うん、やっぱりサボってはいけないよ.
プロジェクト構造
├── build # webpack    
│   ├── build.js
│   ├── config.js
│   ├── run-env.js
│   ├── utils.js
│   ├── webpack.config.base.js
│   ├── webpack.config.dev.js
│   └── webpack.config.prod.js
├── dist #          
│   ├── commons.bundle.js
│   ├── css
│   │   ├── index.eb8584e93d4fbcbec235.css
│   │   └── test.eb8584e93d4fbcbec235.css
│   ├── img
│   │   └── test.d7a9b40f5bed4003db2585ba1bf24d86.jpg
│   ├── index.html
│   ├── js
│   │   ├── index.bundle.eb8584e93d4fbcbec235.js
│   │   └── test.bundle.eb8584e93d4fbcbec235.js
│   └── test.html
├── src #    
│   ├── css
│   │   ├── base.scss
│   │   ├── index.scss
│   │   ├── test.scss
│   │   └── var.scss
│   ├── html
│   │   ├── index.html
│   │   └── test.html
│   ├── img
│   │   └── test.jpg
│   └── js
│       ├── app
│       │   ├── index.js
│       │   └── test.js
│       ├── base
│       └── component
├── webpack.config.js # webpack  

package.json
まずpackage.jsonの命令と依存を見てみましょう
script:
"scripts": {
        "init-page": "node ./init-page.js",
        "dev": "export NODE_ENV=development && webpack-dev-server --open",
        "build": "export NODE_ENV=production && node ./build/build.js"
    }

依存関係:
"devDependencies": {
        "babel-core": "^6.26.0",
        "babel-loader": "^7.1.2",
        "babel-preset-env": "^1.6.0",
        "clean-webpack-plugin": "^0.1.17",
        "css-loader": "^0.28.7",
        "eslint": "^4.10.0",
        "eslint-config-standard": "^10.2.1",
        "eslint-plugin-html": "^3.2.2",
        "eslint-plugin-import": "^2.8.0",
        "eslint-plugin-node": "^5.2.1",
        "eslint-plugin-promise": "^3.6.0",
        "eslint-plugin-standard": "^3.0.1",
        "exports-loader": "^0.6.4",
        "extract-text-webpack-plugin": "^3.0.1",
        "file-loader": "^1.1.5",
        "html-webpack-plugin": "^2.30.1",
        "html-withimg-loader": "^0.1.16",
        "node-sass": "^4.5.3",
        "postcss-loader": "^2.0.7",
        "preprocess-loader": "^0.2.2",
        "sass-loader": "^6.0.6",
        "script-loader": "^0.7.2",
        "style-loader": "^0.19.0",
        "url-loader": "^0.6.2",
        "webpack": "^3.7.1",
        "webpack-dev-server": "^2.9.1",
        "webpack-merge": "^4.1.0"
    }

Webpackエントリ構成
Webpackのエントリファイルはwebpack.config.jsで、このファイルではコマンドに従って対応するwebpack構成を実行します.
const env = process.env.NODE_ENV === 'production' ? 'prod' : 'dev';
//           
module.exports = require(`./build/webpack.config.${env}.js`);

Webpackインフラストラクチャwebpack.base.config.jsでは、loaderやファイルのクリーンアップなど、webpackの一般的な処理が含まれています.複数ページのアプリケーションを構成するため、エントリファイルの処理も面倒です.マルチエントリファイルの処理にはhtml-webpack-pluginというプラグインが使用される.使用する前にhtmlファイル名をすべて取得する必要があります.これはnodeのfsおよびpath apiを使用して取得しました.
/*  html   */
module.exports = {
    getFileNameList(path) {
        let fileList = [];
        let dirList = fs.readdirSync(path);
        dirList.forEach(item => {
            if (item.indexOf('html') > -1) {
                fileList.push(item.split('.')[0]);
            }
        });
        return fileList;
    }
};

Webpackエントリおよびhtml pluginを処理します.
//   html  
let HTMLDirs = utils.getFileNameList('./src/html');

let HTMLPlugins = [];

//         
let entries = {};
HTMLDirs.forEach(page => {
    const htmlPlugin = new HTMLWebpackPlugin({
        filename: `${page}.html`,
        template: path.resolve(__dirname, `../src/html/${page}.html`),
        chunks: [page, 'commons']
    });
    HTMLPlugins.push(htmlPlugin);
    entries[page] = path.resolve(__dirname, `../src/js/app/${page}.js`);
});

関連webpack構成、具体的な構成はgithubを参照
// webpack  
module.exports = {
    entry: entries,
    ...
    plugins: [
        //      HTML   
        ...HTMLPlugins
    ]
};

最も複雑で面倒なのはすべてbaseの中でやり終わって、ローカル開発とパッケージbuildはいくつかの簡単な処理をすればokです
Webpackローカル開発ファイル構成とパッケージラインファイル構成
ローカルとオンラインのプロファイルは、baseの構成(webpack-mergeでこの作業を処理できる)をマージしてから、簡単な処理をすればいいです.
// dev
module.exports = webpackMerge(webpackBase, {
    devServer: {
        contentBase: config.devServerOutputPath,
        overlay: {
            errors: true,
            warnings: true
        }
    }
});
// prod
module.exports = webpackMerge(webpackBase, {
    devtool: false,
    plugins: [
        //     
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            }
        }),
        //      JavaScript   
        new webpack.optimize.CommonsChunkPlugin({
            // chunk    commons
            name: 'commons',
            filename: '[name].bundle.js'
        })
    ]
});


zepto等のモジュール化されていないライブラリの処理
zeptoのようなモジュール化されていないライブラリを処理するときに私が取った方法はcdnロードで、webpack構成に外部拡張を加えることです(externalsは、一部のimportのパッケージをbundleにパッケージ化するのを防止することができ、実行時に外部からこれらの拡張依存性を取得することができます).
externals: {
    'zepto': '$'
}

preprocess
これまでこの案は三端のH 5とandroid、iosを埋め込んだwebviewを作るため、プラットフォームに応じて特殊な処理が必要だった.gulpにはgulp-preprocessがあり、webpackではpreprocess-loaderを使用して処理することができます.
{
    test: /\.(html|js|css|scss)$/,
    loader: `preprocess-loader?${runEnv}`
}

後記
しばらくはこれだけしかしていませんが、このツールはまだ正式に使用されていないので、問題が多いと思います.その後、問題があれば補充を続けます.
読んでくれてありがとう.本文は趙の親指の著作権で所有されています.原文住所:https://www.zhaofinger.com/detail/11