如何构建/部署角度2项目到生产?

时间:2016-09-15 17:52:57

标签: javascript node.js angular

我使用Angular 2创建了一个站点。我开始使用Angular 2 QuickStart Guide作为基础创建我的站点,如果我使用命令npm start,它的工作方式应该如此。现在网站已经完成,我需要为生产构建/部署(不知道正确的定义),以便站点可以访问客户端。问题是:如何构建这个项目用于生产? (无需运行npm install

我能找到的最好的事情是尝试ng build -prod,但它说我的项目不是一个cli项目。如何生成独立文件以仅打开index.html页面并访问该站点?有可能吗?

更新

也许我不清楚:我正在寻找的是获取所有TypeScripts文件并在纯HTML / JavaScript / CSS站点中构建它以便显示的方法。目前不需要压缩或缩小。可能吗?如果没有,那么其他解决方案是什么(最好是独立于主机)?

3 个答案:

答案 0 :(得分:0)

因此,根据我对使用Angular2的理解,过去几周您实际创建的是一个客户端单页应用程序,因此您需要提供的只是HTML页面,其中包含对相应JavaScript文件的引用。

我一直在调查WebPack打包应用程序(并且仍处于正确的状态),但是,WebPack会将所有已编译的打字稿文件合并为一个(或多个,仍然在这部分工作) Javascript文件同时还将对javascript文件的引用注入index.html页面。

我当前的项目使用web pack配置编译打字稿文件(使用gulp)来配置输出javascript文件(main.ts - > main.js):

gulp.task("build-tsc", function() {
    return gulp.src("entry.js")
        .pipe(webpack( require("../../../webpack.config.js")))
        .pipe(gulp.dest(config.dist));
});

我的web pack.config.js看起来像(webpack模块忽略了我没有entry.js的事实):

var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require('webpack');

module.exports = {
  entry: {
    "main": "./src/app/main.ts",
    "share": "./src/app/share_main.ts",
    "polyfills": "./src/app/polyfills.ts"
  },
  output: {
    path: __dirname,
    filename: "[name].js"
  },
  module: {
    loaders: [
      { test: /\.css$/, loader: "style!css" },
      { test: /\.ts$/, loader: 'ts-loader' }
    ]
  },
  resolve: {
    extensions: ['', '.js', '.ts']
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: ['main', 'share', 'polyfills']
    }),
    new HtmlWebpackPlugin({
      template: 'src/index.html'
    })
  ]
};

我原来的代码库是:

src/
    index.html
    assets/
        styles/
            main.scss
    app/
        app.component.ts
        app.routes.ts
        app.module.ts
        share_main.ts
        polyfills.ts
        dashboard/
            dashboard.component.ts
            dashboard.html
        navbar/
            navbar.component.ts
            navbar.html

所以我最终得到的(post build)是一个新的dist /目录,其中包含文件供使用:

dist/
    index.html
    main.js
    share.js
    polyfill.js
    app/
        dashboard/
            dashboard.html
        navbar/
            navbar.html
    styles/
        main.css

现在我正在使用browserSync为开发目的服务文件,但理论上你应该能够通过NGINX,Apache将它们作为静态内容提供,或者通过NGINX / Apache将它们代理到lite-server

WebPack背后的想法是你给它一个入口点(在本例中是main.ts)并且它抓取import语句,确保它遇到的任何东西被添加到生成的Javascript文件中,然后将它们添加到index.html文件中自动。

就像我提到的那样,我有一个有效的应用程序,但我试图理解"多个入口点"更好,但上述应该是一样的。

答案 1 :(得分:0)

我在处理webpack时非常糟糕,并且无法使用Anthony Ikeda解决方案或我在网络上找到的任何其他解决方案。如果有人像我一样陷入困境,我的解决方案是使用Angular Cli。我使用angular cli创建一个新项目,使用angular cli创建所有页面,组件和服务,并将旧的no-cli项目中的代码复制到这个新的cli项目中。使用cli项目,我使用ng build命令构建项目并获取要部署的文件。

答案 2 :(得分:0)

我使用这个解决方案,它对我来说非常合适(只有html + css + js文件)...只有缩小才能给我带来一些问题。

我的webpack.config.js:

/// <binding />
var environment = (process.env.NODE_ENV || "development").trim();

if (environment === "development") {
    module.exports = require('./webpack.dev.js');
} else {
    module.exports = require('./webpack.prod.js');
}

我的webpack.dev.js

var ExtractTextPlugin = require("extract-text-webpack-plugin");
var webpack = require("webpack");
var HtmlWebpackPlugin = require("html-webpack-plugin");
var CleanWebpackPlugin = require('clean-webpack-plugin');
var path = require('path');

module.exports = {
    entry: {
        "polyfills": "./polyfills.ts",
        "vendor": "./vendor.ts",
        "app": "./app/main.ts",

    },
    resolve: {
        extensions: ['', '.ts', '.js', '.json', '.css', '.scss', '.html']
    },
    output: {
        path: "./app_build",
        filename: "js/[name]-[hash:8].bundle.js"
    },
    devtool: 'source-map',
    module: {
        loaders: [
            {
                loader: "babel-loader",

                // Skip any files outside of your project's `src` directory
                //include: [
                //  "app_build",
                //],
                exclude: [
                  path.resolve(__dirname, "node_modules")
                ],
                // Only run `.js` and `.jsx` files through Babel
                test: /\.js/,

                // Options to configure babel with
                query: {
                    plugins: ['transform-runtime', 'babel-plugin-transform-async-to-generator'],
                    presets: ['es2015', 'stage-0'],
                }
            },
            {
                test: /\.ts$/,
                loader: "ts"
            },
            {
                test: /\.html$/,
                loader: "html"
            },
            //{
            //    test: /\.(png|jpg|gif|ico|woff|woff2|ttf|svg|eot)$/,
            //    loader: "file?name=assets/[name]-[hash:6].[ext]",
            //},
            {
                test: /\.(png|jpg|gif|ico)$/,
                //include:  path.resolve(__dirname, "assets/img"),
                loader: 'file?name=/assets/img/[name]-[hash:6].[ext]'
            },
            {
                test: /\.(woff|woff2|eot|ttf|svg)$/,
              //  exclude: /node_modules/,
                loader: 'file?name=/assets/fonts/[name].[ext]'
            },
            // Load css files which are required in vendor.ts
            {
                test: /\.css$/,
                loader: "style-loader!css-loader"
            },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract('css!sass')
            },
        ]
    },
    plugins: [
        new ExtractTextPlugin("css/[name]-[hash:8].bundle.css", { allChunks: true }),
        new webpack.optimize.CommonsChunkPlugin({
            name: ["app", "vendor", "polyfills"]
        }),
        new CleanWebpackPlugin(
            [
                "./app_build/js/",
                "./app_build/css/",
                "./app_build/assets/",
                "./app_build/index.html"
            ]
        ),
        // inject in index.html
        new HtmlWebpackPlugin({
            template: "./index.html",
            inject: "body"
        }),
        new webpack.ProvidePlugin({
            jQuery: 'jquery',
            $: 'jquery',
            jquery: 'jquery'
        })
    ],
    devServer: {
        //contentBase: path.resolve(__dirname, "app_build/"),
        historyApiFallback: true,
        stats: "minimal"
    }
};

我的webpack.prod.js:

var ExtractTextPlugin = require("extract-text-webpack-plugin");
var webpack = require("webpack");
var HtmlWebpackPlugin = require("html-webpack-plugin");
var CleanWebpackPlugin = require('clean-webpack-plugin');
var path = require('path');
var BabiliPlugin = require("babili-webpack-plugin");

module.exports = {
    entry: {
        "polyfills": "./polyfills.ts",
        "vendor": "./vendor.ts",
        "app": "./app/main.ts"
    },
    resolve: {
        extensions: ['', '.ts', '.js', '.json', '.css', '.scss', '.html']
    },
    output: {
        path: "./app_build",
        filename: "js/[name]-[hash:8].bundle.min.js"
    },

    module: {
        loaders: [
           {
               loader: "babel-loader",

               // Skip any files outside of your project's `src` directory
               //include: [
               //  "app_build",
               //],
               exclude: [
                 path.resolve(__dirname, "node_modules")
               ],
               // Only run `.js` and `.jsx` files through Babel
               test: /\.js/,

               // Options to configure babel with
               query: {
                   plugins: ['transform-runtime', 'babel-plugin-transform-async-to-generator'],
                   presets: ['es2015', 'stage-0'],
               }
           },
           {
               test: /\.ts$/,
               loader: "ts"
           },
           {
               test: /\.html$/,
               loader: "html"
           },
           //{
           //    test: /\.(png|jpg|gif|ico|woff|woff2|ttf|svg|eot)$/,
           //    loader: "file?name=assets/[name]-[hash:6].[ext]",
           //},
           {
               test: /\.(png|jpg|gif|ico)$/,
               //include:  path.resolve(__dirname, "assets/img"),
               loader: 'file?name=assets/img/[name]-[hash:6].[ext]'
           },
           {
               test: /\.(woff|woff2|eot|ttf|svg)$/,
               //  exclude: /node_modules/,
               loader: 'file?name=/assets/fonts/[name].[ext]'
           },
           // Load css files which are required in vendor.ts
           {
               test: /\.css$/,
               loader: "style-loader!css-loader"
           },
           {
               test: /\.scss$/,
               loader: ExtractTextPlugin.extract('css!sass')
           },
        ]
    },
    plugins: [
        new ExtractTextPlugin("css/[name]-[hash:8].bundle.css", { allChunks: true }),
        new webpack.optimize.CommonsChunkPlugin({
            name: ["app", "vendor", "polyfills"]
        }),
        new CleanWebpackPlugin(
            [
                "./app_build/js/",
                "./app_build/css/",
                "./app_build/assets/",
                "./app_build/index.html"
            ]
        ),
        // inject in index.html
        new HtmlWebpackPlugin({
            template: "./index.html",
            inject: "body"
        }),
        new BabiliPlugin({ comments: false }),
        new webpack.ProvidePlugin({
            jQuery: 'jquery',
            $: 'jquery',
            jquery: 'jquery'
        })
    ],
    devServer: {
        historyApiFallback: true,
        stats: "minimal"
    }
};

然后我的package.json(带有为prod构建的命令):

{
  "name": "dipendentistatali",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "start": "tsc && npm install && npm run build",
    "watch": "SET NODE_ENV=development && webpack --watch --color",
    "test": "webpack-dev-server --inline --hot",
    "build": "SET NODE_ENV=development && webpack -d --color",
    "buildProduction": "SET NODE_ENV=production && webpack -d --color",
    "lint": "tslint ./app/**/*.ts -t verbose",
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings"
  },
  "keywords": [],
  "author": "",
  "dependencies": {
    "@angular/common": "2.1.1",
    "@angular/compiler": "2.1.1",
    "@angular/core": "2.1.1",
    "@angular/forms": "2.1.1",
    "@angular/http": "2.1.1",
    "@angular/platform-browser": "2.1.1",
    "@angular/platform-browser-dynamic": "2.1.1",
    "@angular/router": "3.0.0",
    "@angular/upgrade": "2.0.0",
    "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.15",
    "angular2-cool-http": "^1.2.3",
    "angular2-toaster": "^1.0.1",
    "babel-plugin-transform-async-to-generator": "^6.16.0",
    "bootstrap": "^3.3.6",
    "core-js": "^2.4.1",
    "jquery": "2.2.4",
    "ng2-bs3-modal": "^0.10.4",
    "ng2-modal": "0.0.22",
    "ng2-resource-rest": "^1.5.3",
    "ng2-slim-loading-bar": "^2.0.4",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.12",
    "systemjs": "0.19.27",
    "zone.js": "^0.6.23"
  },
  "devDependencies": {
    "babel-cli": "^6.18.0",
    "babel-core": "^6.18.2",
    "babel-loader": "^6.2.7",
    "babel-plugin-transform-es2015-arrow-functions": "^6.8.0",
    "babel-plugin-transform-runtime": "^6.15.0",
    "babel-preset-es2015": "^6.18.0",
    "clean-webpack-plugin": "0.1.10",
    "concurrently": "^2.2.0",
    "css-loader": "^0.23.1",
    "extract-text-webpack-plugin": "^1.0.1",
    "file-loader": "^0.8.5",
    "html-loader": "^0.4.3",
    "html-webpack-plugin": "^2.15.0",
    "lite-server": "^2.2.2",
    "lodash": "^4.11.1",
    "node-sass": "^3.13.0",
    "raw-loader": "^0.5.1",
    "rimraf": "^2.5.2",
    "sass-loader": "^3.2.3",
    "style-loader": "^0.13.1",
    "ts-loader": "^0.8.1",
    "tslint": "^3.7.4",
    "typescript": "^2.0.2",
    "typings": "^1.3.2",
    "webpack": "^1.14.0",
    "webpack-dev-server": "^1.16.2",
    "webpack-merge": "^0.9.0",
    "webpack-stream": "^3.2.0"
  }
}

因此,如果您启动npm start build,它会在我称为app_build /

的目录中构建prod版本

希望它可以帮到你