Gulp + Webpack hay JUST Webpack?

163
PositiveGuy 2015-11-06 16:19.

Tôi thấy mọi người đang sử dụng webpack. Nhưng sau đó tôi đọc webpack có thể thay thế gulp? Tôi hoàn toàn bối rối ở đây ... ai đó có thể giải thích?

CẬP NHẬT

cuối cùng, tôi bắt đầu với sự nuốt chửng. Tôi chưa quen với giao diện người dùng hiện đại và chỉ muốn khởi động nhanh chóng. Bây giờ tôi đã khá chân ướt chân ráo sau hơn một năm, tôi đã sẵn sàng để chuyển sang webpack. Tôi đề xuất cùng một lộ trình cho những người bắt đầu với cùng một đôi giày. Không nói rằng bạn không thể thử webpack nhưng chỉ nói nếu nó có vẻ phức tạp, hãy bắt đầu bằng cách nuốt chửng trước ... không có gì sai với điều đó.

Nếu bạn không muốn nuốt chửng, vâng, có nhưng bạn cũng có thể chỉ định các lệnh trong package.json của mình và gọi chúng từ dòng lệnh mà không cần trình chạy tác vụ chỉ để khởi động và chạy ban đầu. Ví dụ:

"scripts": {
      "babel": "babel src -d build",
      "browserify": "browserify build/client/app.js -o dist/client/scripts/app.bundle.js",
      "build": "npm run clean && npm run babel && npm run prepare && npm run browserify",
      "clean": "rm -rf build && rm -rf dist",
      "copy:server": "cp build/server.js dist/server.js",
      "copy:index": "cp src/client/index.html dist/client/index.html",
      "copy": "npm run copy:server && npm run copy:index",
      "prepare": "mkdir -p dist/client/scripts/ && npm run copy",
      "start": "node dist/server"
    },

5 answers

83
4m1r 2015-11-07 12:18.

Câu trả lời này có thể hữu ích. Task Runners (Gulp, Grunt, v.v.) và Bundlers (Webpack, Browserify). Tại sao lại sử dụng cùng nhau?

... và đây là một ví dụ về việc sử dụng webpack từ bên trong một tác vụ gulp. Điều này tiến xa hơn một bước và giả định rằng cấu hình webpack của bạn được viết bằng es6.

var gulp = require('gulp');
var webpack = require('webpack');
var gutil = require('gutil');
var babel = require('babel/register');
var config = require(path.join('../..', 'webpack.config.es6.js'));

gulp.task('webpack-es6-test', function(done){
   webpack(config).run(onBuild(done));
});

function onBuild(done) {
    return function(err, stats) {
        if (err) {
            gutil.log('Error', err);
            if (done) {
                done();
            }
        } else {
            Object.keys(stats.compilation.assets).forEach(function(key) {
                gutil.log('Webpack: output ', gutil.colors.green(key));
            });
            gutil.log('Webpack: ', gutil.colors.blue('finished ', stats.compilation.name));
            if (done) {
                done();
            }
        }
    }
}

Tôi nghĩ bạn sẽ thấy rằng khi ứng dụng của bạn trở nên phức tạp hơn, bạn có thể muốn sử dụng gulp với tác vụ webpack như ví dụ ở trên. Điều này cho phép bạn thực hiện một số điều thú vị hơn trong bản dựng của mình mà các trình tải và plugin webpack thực sự không làm được. tạo thư mục đầu ra, khởi động máy chủ, v.v ... Nói một cách ngắn gọn, webpack thực sự có thể làm những việc đó, nhưng bạn có thể thấy chúng bị hạn chế đối với nhu cầu lâu dài của mình. Một trong những lợi thế lớn nhất bạn nhận được từ gulp -> webpack là bạn có thể tùy chỉnh cấu hình webpack của mình cho các môi trường khác nhau và yêu cầu gulp thực hiện đúng nhiệm vụ vào đúng thời điểm. Nó thực sự tùy thuộc vào bạn, nhưng không có gì sai khi chạy webpack từ gulp, trên thực tế, có một số ví dụ khá thú vị về cách thực hiện. Ví dụ trên về cơ bản là từ jlongster .

80
TetraDev 2016-08-27 12:01.

Các tập lệnh NPM có thể làm tương tự như gulp, nhưng với ít mã hơn khoảng 50 lần. Trong thực tế, không có mã nào cả, chỉ có các đối số dòng lệnh.

Ví dụ: trường hợp sử dụng bạn đã mô tả nơi bạn muốn có mã khác nhau cho các môi trường khác nhau.

Với Webpack + NPM Scripts, thật dễ dàng:

"prebuild:dev": "npm run clean:wwwroot",
"build:dev": "cross-env NODE_ENV=development webpack --config config/webpack.development.js --hot --profile --progress --colors --display-cached",
"postbuild:dev": "npm run copy:index.html && npm run rename:index.html",

"prebuild:production": "npm run clean:wwwroot",
"build:production": "cross-env NODE_ENV=production webpack --config config/webpack.production.js --profile --progress --colors --display-cached --bail",
"postbuild:production": "npm run copy:index.html && npm run rename:index.html",

"clean:wwwroot": "rimraf -- wwwroot/*",
"copy:index.html": "ncp wwwroot/index.html Views/Shared",
"rename:index.html": "cd ../PowerShell && elevate.exe -c renamer --find \"index.html\" --replace \"_Layout.cshtml\" \"../MyProject/Views/Shared/*\"",

Bây giờ bạn chỉ cần duy trì hai tập lệnh cấu hình webpack, một cho chế độ phát triển webpack.development.jsvà một cho chế độ sản xuất webpack.production.js,. Tôi cũng sử dụng một webpack.common.jsnơi chứa cấu hình webpack được chia sẻ trên tất cả các môi trường và sử dụng webpackMerge để hợp nhất chúng.

Bởi vì sự mát mẻ của các tập lệnh NPM, nó cho phép dễ dàng xâu chuỗi, tương tự như cách nuốt Luồng / đường ống.

Trong ví dụ trên, để xây dựng để phát triển, bạn chỉ cần vào dòng lệnh của mình và thực thi npm run build:dev.

  1. NPM sẽ chạy lần đầu tiên prebuild:dev,
  2. Sau đó build:dev,
  3. Và cuối cùng postbuild:dev.

Các preposttiền tố nói NPM đó để thực hiện trong.

Nếu bạn nhận thấy, với các tập lệnh Webpack + NPM, bạn có thể chạy một chương trình gốc, chẳng hạn như rimraf, thay vì một trình bao bọc cho một chương trình gốc chẳng hạn gulp-rimraf. Bạn cũng có thể chạy các tệp .exe gốc của Windows như tôi đã làm ở đây với elevate.exehoặc các tệp * nix gốc trên Linux hoặc Mac.

Hãy thử làm điều tương tự với nuốt nước bọt. Bạn sẽ phải đợi ai đó đi cùng và viết một bản tóm tắt cho chương trình gốc mà bạn muốn sử dụng. Ngoài ra, bạn có thể sẽ cần phải viết mã phức tạp như sau: (lấy thẳng từ repo angle2-seed )

Mã phát triển Gulp

import * as gulp from 'gulp';
import * as gulpLoadPlugins from 'gulp-load-plugins';
import * as merge from 'merge-stream';
import * as util from 'gulp-util';
import { join/*, sep, relative*/ } from 'path';

import { APP_DEST, APP_SRC, /*PROJECT_ROOT, */TOOLS_DIR, TYPED_COMPILE_INTERVAL } from '../../config';
import { makeTsProject, templateLocals } from '../../utils';

const plugins = <any>gulpLoadPlugins();

let typedBuildCounter = TYPED_COMPILE_INTERVAL; // Always start with the typed build.

/**
 * Executes the build process, transpiling the TypeScript files (except the spec and e2e-spec files) for the development
 * environment.
 */
export = () => {
  let tsProject: any;
  let typings = gulp.src([
    'typings/index.d.ts',
    TOOLS_DIR + '/manual_typings/**/*.d.ts'
  ]);
  let src = [
    join(APP_SRC, '**/*.ts'),
    '!' + join(APP_SRC, '**/*.spec.ts'),
    '!' + join(APP_SRC, '**/*.e2e-spec.ts')
  ];

  let projectFiles = gulp.src(src);
  let result: any;
  let isFullCompile = true;

  // Only do a typed build every X builds, otherwise do a typeless build to speed things up
  if (typedBuildCounter < TYPED_COMPILE_INTERVAL) {
    isFullCompile = false;
    tsProject = makeTsProject({isolatedModules: true});
    projectFiles = projectFiles.pipe(plugins.cached());
    util.log('Performing typeless TypeScript compile.');
  } else {
    tsProject = makeTsProject();
    projectFiles = merge(typings, projectFiles);
  }

  result = projectFiles
    .pipe(plugins.plumber())
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.typescript(tsProject))
    .on('error', () => {
      typedBuildCounter = TYPED_COMPILE_INTERVAL;
    });

  if (isFullCompile) {
    typedBuildCounter = 0;
  } else {
    typedBuildCounter++;
  }

  return result.js
    .pipe(plugins.sourcemaps.write())
// Use for debugging with Webstorm/IntelliJ
// https://github.com/mgechev/angular2-seed/issues/1220
//    .pipe(plugins.sourcemaps.write('.', {
//      includeContent: false,
//      sourceRoot: (file: any) =>
//        relative(file.path, PROJECT_ROOT + '/' + APP_SRC).replace(sep, '/') + '/' + APP_SRC
//    }))
    .pipe(plugins.template(templateLocals()))
    .pipe(gulp.dest(APP_DEST));
};

Mã sản xuất Gulp

import * as gulp from 'gulp';
import * as gulpLoadPlugins from 'gulp-load-plugins';
import { join } from 'path';

import { TMP_DIR, TOOLS_DIR } from '../../config';
import { makeTsProject, templateLocals } from '../../utils';

const plugins = <any>gulpLoadPlugins();

const INLINE_OPTIONS = {
  base: TMP_DIR,
  useRelativePaths: true,
  removeLineBreaks: true
};

/**
 * Executes the build process, transpiling the TypeScript files for the production environment.
 */

export = () => {
  let tsProject = makeTsProject();
  let src = [
    'typings/index.d.ts',
    TOOLS_DIR + '/manual_typings/**/*.d.ts',
    join(TMP_DIR, '**/*.ts')
  ];
  let result = gulp.src(src)
    .pipe(plugins.plumber())
    .pipe(plugins.inlineNg2Template(INLINE_OPTIONS))
    .pipe(plugins.typescript(tsProject))
    .once('error', function () {
      this.once('finish', () => process.exit(1));
    });


  return result.js
    .pipe(plugins.template(templateLocals()))
    .pipe(gulp.dest(TMP_DIR));
};

Mã gulp thực tế phức tạp hơn nhiều, vì đây chỉ là 2 trong số hàng chục tệp gulp trong repo.

Vì vậy, cái nào là dễ dàng hơn cho bạn?

Theo ý kiến ​​của tôi, các tập lệnh NPM vượt xa cả gulp và grunt, về cả tính hiệu quả và dễ sử dụng, và tất cả các nhà phát triển front-end nên cân nhắc sử dụng nó trong quy trình làm việc của họ vì nó là một cách tiết kiệm thời gian chính.

CẬP NHẬT

Có một tình huống tôi gặp phải khi tôi muốn sử dụng Gulp kết hợp với các tập lệnh NPM và Webpack.

Ví dụ: khi tôi cần gỡ lỗi từ xa trên iPad hoặc thiết bị Android, tôi cần khởi động thêm máy chủ. Trước đây, tôi đã chạy tất cả các máy chủ dưới dạng các quy trình riêng biệt, từ bên trong IntelliJ IDEA (Hoặc Webstorm) dễ dàng với Cấu hình Chạy "Hợp chất". Nhưng nếu tôi cần dừng và khởi động lại chúng, thật tẻ nhạt khi phải đóng 5 tab máy chủ khác nhau, cộng với đầu ra trải dài trên các cửa sổ khác nhau.

Một trong những lợi ích của gulp là có thể liên kết tất cả đầu ra từ các quy trình độc lập riêng biệt vào một cửa sổ giao diện điều khiển, cửa sổ này trở thành cha của tất cả các máy chủ con.

Vì vậy, tôi đã tạo một tác vụ gulp rất đơn giản chỉ chạy trực tiếp các tập lệnh NPM của tôi hoặc các lệnh, vì vậy tất cả đầu ra xuất hiện trong một cửa sổ và tôi có thể dễ dàng kết thúc tất cả 5 máy chủ cùng một lúc bằng cách đóng cửa sổ tác vụ gulp.

Gulp.js

/**
 * Gulp / Node utilities
 */
var gulp = require('gulp-help')(require('gulp'));
var utils = require('gulp-util');
var log = utils.log;
var con = utils.colors;

/**
 * Basic workflow plugins
 */
var shell = require('gulp-shell'); // run command line from shell
var browserSync = require('browser-sync');

/**
 * Performance testing plugins
 */
var ngrok = require('ngrok');

// Variables
var serverToProxy1 = "localhost:5000";
var finalPort1 = 8000;


// When the user enters "gulp" on the command line, the default task will automatically be called. This default task below, will run all other tasks automatically.

// Default task
gulp.task('default', function (cb) {
   console.log('Starting dev servers!...');
   gulp.start(
      'devserver:jit',
      'nodemon',
      'browsersync',
      'ios_webkit_debug_proxy'
      'ngrok-url',
      // 'vorlon',
      // 'remotedebug_ios_webkit_adapter'
   );
});

gulp.task('nodemon', shell.task('cd ../backend-nodejs && npm run nodemon'));
gulp.task('devserver:jit', shell.task('npm run devserver:jit'));
gulp.task('ios_webkit_debug_proxy', shell.task('npm run ios-webkit-debug-proxy'));
gulp.task('browsersync', shell.task(`browser-sync start --proxy ${serverToProxy1} --port ${finalPort1} --no-open`));
gulp.task('ngrok-url', function (cb) {
   return ngrok.connect(finalPort1, function (err, url) {
      site = url;
      log(con.cyan('ngrok'), '- serving your site from', con.yellow(site));
      cb();
   });
});
// gulp.task('vorlon', shell.task('vorlon'));
// gulp.task('remotedebug_ios_webkit_adapter', shell.task('remotedebug_ios_webkit_adapter'));

Vẫn còn khá nhiều mã chỉ để chạy 5 tác vụ, theo ý kiến ​​của tôi, nhưng nó hoạt động đúng mục đích. Một lưu ý là gulp-shelldường như không chạy một số lệnh chính xác, chẳng hạn như ios-webkit-debug-proxy. Vì vậy, tôi phải tạo một Tập lệnh NPM chỉ thực thi cùng một lệnh và sau đó nó hoạt động.

Vì vậy, tôi chủ yếu sử dụng NPM Scripts cho tất cả các nhiệm vụ của mình, nhưng đôi khi khi tôi cần chạy nhiều máy chủ cùng một lúc, tôi sẽ kích hoạt nhiệm vụ Gulp của mình để trợ giúp. Chọn đúng công cụ cho công việc phù hợp.

CẬP NHẬT 2

Bây giờ tôi sử dụng một tập lệnh được gọi là đồng thời thực hiện điều tương tự như tác vụ gulp ở trên. Nó chạy song song nhiều tập lệnh CLI và đưa tất cả chúng vào cùng một cửa sổ bảng điều khiển và rất đơn giản để sử dụng. Một lần nữa, không cần mã (tốt, mã nằm bên trong node_module đồng thời, nhưng bạn không cần phải lo lắng về điều đó)

// NOTE: If you need to run a command with spaces in it, you need to use 
// double quotes, and they must be escaped (at least on windows).
// It doesn't seem to work with single quotes.

"run:all": "concurrently \"npm run devserver\" nodemon browsersync ios_webkit_debug_proxy ngrok-url"

Điều này chạy tất cả 5 tập lệnh song song được chuyển đến một thiết bị đầu cuối. Tuyệt vời! Vì vậy, điểm này, tôi hiếm khi sử dụng gulp, vì có rất nhiều đoạn mã để thực hiện các tác vụ tương tự mà không cần mã.

Tôi khuyên bạn nên đọc những bài báo này để so sánh chúng một cách chuyên sâu.

8
R.R 2016-02-29 13:01.

Tôi đã sử dụng cả hai tùy chọn trong các dự án khác nhau của mình.

Đây là một bản ghi sẵn mà tôi sử dụng gulpcùng với webpack- https://github.com/iroy2000/react-reflux-boilerplate-with-webpack .

Tôi có một số dự án khác chỉ được sử dụng webpackvới npm tasks.

Và cả hai đều hoạt động hoàn toàn tốt. Và tôi nghĩ vấn đề mấu chốt là nhiệm vụ của bạn phức tạp đến mức nào và bạn muốn có bao nhiêu quyền kiểm soát trong cấu hình của mình.

Ví dụ, nếu bạn nhiệm vụ là đơn giản, giả sử dev, build, test... vv (mà là rất chuẩn), bạn hoàn toàn tốt với chỉ đơn giản webpackvới npm tasks.

Nhưng nếu bạn có quy trình làm việc rất phức tạp và bạn muốn kiểm soát nhiều hơn cấu hình của mình (vì nó là mã hóa), bạn có thể đi theo lộ trình gulp.

Nhưng theo kinh nghiệm của tôi, hệ sinh thái webpack cung cấp quá đủ các plugin và trình tải mà tôi sẽ cần, và vì vậy tôi thích sử dụng phương pháp tối thiểu trần trừ khi có điều gì đó bạn chỉ có thể làm. Ngoài ra, nó sẽ giúp cấu hình của bạn dễ dàng hơn nếu bạn có một thứ trong hệ thống của mình.

Và rất nhiều lần, ngày nay, tôi thấy mọi người thực sự thay thế gulp and browsifytất cả bằng webpackmột mình.

2
Maokai 2018-01-12 09:23.

Các khái niệm về Gulp và Webpack khá khác nhau. Bạn nói với Gulp cách đặt mã front-end với nhau từng bước một, nhưng bạn cho Webpack biết bạn muốn gì thông qua một tệp cấu hình.

Đây là một bài báo ngắn (5 phút đọc) tôi đã viết giải thích sự hiểu biết của tôi về sự khác biệt: https://medium.com/@Maokai/compile-the-front-end-from-gulp-to-webpack-c45671ad87fe

Công ty chúng tôi đã chuyển từ Gulp sang Webpack trong năm qua. Mặc dù mất một khoảng thời gian nhưng chúng tôi đã tìm ra cách chuyển tất cả những gì chúng tôi đã làm trong Gulp sang Webpack. Vì vậy, với chúng tôi, mọi thứ chúng tôi đã làm trong Gulp chúng tôi cũng có thể thực hiện thông qua Webpack, nhưng không phải ngược lại.

Kể từ hôm nay, tôi khuyên bạn chỉ nên sử dụng Webpack và tránh sự kết hợp của Gulp và Webpack để bạn và nhóm của bạn không cần phải học và duy trì cả hai, đặc biệt là vì chúng đòi hỏi những tư duy rất khác nhau.

2
Max Favilli 2018-02-02 04:55.

Thành thật mà nói tôi nghĩ tốt nhất là sử dụng cả hai.

  • Webpack cho tất cả javascript liên quan.
  • Gulp cho tất cả css liên quan.

Tôi vẫn phải tìm một giải pháp phù hợp để đóng gói css với webpack và cho đến nay tôi vẫn hài lòng khi sử dụng gulp cho css và webpack cho javascript.

Tôi cũng sử dụng npmtập lệnh là @Tetradev như được mô tả. Đặc biệt là vì tôi đang sử dụng Visual Studio, và trong khi NPM Task runnerkhá đáng tin cậy Webpack Task Runner là khá nhiều lỗi .

Related questions

MORE COOL STUFF

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett chia tay chồng sau 3 ngày bên nhau và vẫn kết hôn với anh ấy 25 năm sau

Cate Blanchett đã bất chấp những lời khuyên hẹn hò điển hình khi cô gặp chồng mình.

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Tại sao Michael Sheen là một diễn viên phi lợi nhuận

Michael Sheen là một diễn viên phi lợi nhuận nhưng chính xác thì điều đó có nghĩa là gì?

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Hallmark Star Colin Egglesfield Các món ăn gây xúc động mạnh đối với người hâm mộ tại RomaDrama Live! [Loại trừ]

Ngôi sao của Hallmark Colin Egglesfield chia sẻ về những cuộc gặp gỡ với người hâm mộ ly kỳ tại RomaDrama Live! cộng với chương trình INSPIRE của anh ấy tại đại hội.

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Tại sao bạn không thể phát trực tuyến 'chương trình truyền hình phía Bắc'

Bạn sẽ phải phủi sạch đầu đĩa Blu-ray hoặc DVD để xem tại sao Northern Exposure trở thành một trong những chương trình nổi tiếng nhất của thập niên 90.

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

8 công dụng tuyệt vời của Baking Soda và Giấm

8 công dụng tuyệt vời của Baking Soda và Giấm

Bạn biết đấy, hai sản phẩm này là nguồn điện để làm sạch, riêng chúng. Nhưng cùng với nhau, chúng có một loạt công dụng hoàn toàn khác.

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Hạn hán, biến đổi khí hậu đe dọa tương lai của thủy điện Hoa Kỳ

Thủy điện rất cần thiết cho lưới điện của Hoa Kỳ, nhưng nó chỉ tạo ra năng lượng khi có nước di chuyển. Bao nhiêu nhà máy thủy điện có thể gặp nguy hiểm khi các hồ và sông cạn kiệt?

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Quyên góp tóc của bạn để giúp giữ nước sạch của chúng tôi

Tóc tỉa từ các tiệm và các khoản quyên góp cá nhân có thể được tái sử dụng như những tấm thảm thấm dầu và giúp bảo vệ môi trường.

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Làm thế nào để xây dựng một quả địa cầu từ Scratch

Thời gian, sự kiên nhẫn, thời gian, sự cống hiến và thời gian chỉ là một vài trong số những thứ mà Peter Bellerby cần để thành lập và sau đó điều hành Bellerby & Co. Globemakers, một trong những công ty duy nhất trên Trái đất vẫn sản xuất các quả địa cầu bằng tay.

Năm giai đoạn đau buồn sau khi mất việc làm

Năm giai đoạn đau buồn sau khi mất việc làm

Đó là một ngày thứ Bảy, máy bay của tôi hạ cánh, và tôi đã sẵn sàng để thư giãn trong một kỳ nghỉ cuối tuần ngắn ngủi, khi một email đến trên điện thoại của tôi. Tôi đã mất việc.

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Giữ an toàn cho danh tính của bạn với một cảnh báo đóng băng hoặc gian lận tín dụng

Nếu bạn đã từng bị đánh cắp danh tính của mình, bạn biết đó là một trải nghiệm đáng sợ và căng thẳng. Một cách không phổ biến để ngăn chặn nó? Tín dụng bị đóng băng.

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Buổi ra mắt phần 3 của The Good Place có một học sinh mới: Khán giả

Eleanor (Kristen Bell) dường như đã tình nguyện cho chúng tôi làm vật tưởng nhớ. NBC's The Good Place là một chương trình thích thử thách tốt.

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Forced to Borrow Paris' 'I Love Paris' Sweatshirt After 'Airline Loses All [My] Luggage'

Nicky Hilton Rothschild's luggage got lost, but luckily she has an incredible closet to shop: Sister Paris Hilton's!

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa

Kate Middleton dành một ngày bên bờ nước ở London, cùng với Jennifer Lopez, Julianne Hough và hơn thế nữa. Từ Hollywood đến New York và mọi nơi ở giữa, hãy xem các ngôi sao yêu thích của bạn đang làm gì!

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

17 tuổi bị đâm chết trong khi 4 người khác bị thương trong một cuộc tấn công bằng dao trên sông Wisconsin

Các nhà điều tra đang xem xét liệu nhóm và nghi phạm có biết nhau trước vụ tấn công hay không

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Thanh thiếu niên, Gia đình Florida Hội đồng quản trị trường học về Luật 'Không nói đồng tính': 'Buộc chúng tôi tự kiểm duyệt'

Vụ kiện, nêu tên một số học khu, lập luận rằng dự luật "Không nói đồng tính" được ban hành gần đây của Florida "có hiệu quả im lặng và xóa bỏ học sinh và gia đình LGBTQ +"

Đường băng hạ cánh

Đường băng hạ cánh

Cuối hè đầu thu là mùa hoài niệm. Những chiếc đèn đường chiếu ánh sáng của chúng qua những con đường đẫm mưa, và những chiếc lá dưới chân - màu đỏ cam tắt trong bóng chạng vạng - là lời nhắc nhở về những ngày đã qua.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Hãy tưởng tượng tạo ra một chiến lược nội dung thực sự CHUYỂN ĐỔI. Nó có thể.

Vào năm 2021, tôi khuyến khích bạn suy nghĩ lại mọi thứ bạn biết về khách hàng mà bạn phục vụ và những câu chuyện bạn kể cho họ. Lùi lại.

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Sự mất mát của voi ma mút đã mở ra trái tim tôi để yêu

Vào ngày sinh nhật thứ 9 của Felix The Cat, tôi nhớ về một trong những mất mát lớn nhất trong cuộc đời trưởng thành của tôi - Sophie của tôi vào năm 2013. Tôi đã viết bài luận này và chia sẻ nó trên nền tảng này một thời gian ngắn vào năm 2013.

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Khi bạn không thể trở thành người mà Internet muốn bạn trở thành

Tôi ghét từ "tàu đắm". Mọi người cảm thấy thoải mái trong la bàn đạo đức của riêng mình, và khi làm như vậy, họ thấy mình vượt qua sự phán xét.

Language